From 4edf8e1c6c5eb39fc231d5dd9db5e5588f1453e0 Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Fri, 26 Feb 2021 21:26:24 +0100 Subject: [PATCH 001/219] better yaml error description for type mismatch --- src/YAML_types.f90 | 72 +++++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index b71261d9c..92e2a41ba 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -302,16 +302,22 @@ end subroutine tScalar_assign__ !-------------------------------------------------------------------------------------------------- !> @brief Type guard, guarantee scalar !-------------------------------------------------------------------------------------------------- -function tNode_asScalar(self) result(scalar) +function tNode_asScalar(self,parent_node) result(scalar) - class(tNode), intent(in), target :: self - class(tScalar), pointer :: scalar + class(tNode), intent(in), target :: self + class(tNode), intent(in), optional :: parent_node + class(tScalar), pointer :: scalar select type(self) class is(tScalar) scalar => self class default - call IO_error(706,ext_msg='Expected "scalar"') + if (present(parent_node)) write(6,'(a)') parent_node%asFormattedString() + if(self%isDict()) then + call IO_error(706,ext_msg='Expected "scalar", found "dict"') + else + call IO_error(706,ext_msg='Expected "scalar", found "list"') + endif end select end function tNode_asScalar @@ -320,16 +326,22 @@ end function tNode_asScalar !-------------------------------------------------------------------------------------------------- !> @brief Type guard, guarantee list !-------------------------------------------------------------------------------------------------- -function tNode_asList(self) result(list) +function tNode_asList(self,parent_node) result(list) - class(tNode), intent(in), target :: self - class(tList), pointer :: list + class(tNode), intent(in), target :: self + class(tNode), intent(in),optional :: parent_node + class(tList), pointer :: list select type(self) class is(tList) list => self class default - call IO_error(706,ext_msg='Expected "list"') + if (present(parent_node)) write(6,'(a)') parent_node%asFormattedString() + if(self%isScalar()) then + call IO_error(706,ext_msg='Expected "list", found "scalar"') + else + call IO_error(706,ext_msg='Expected "list", found "dict"') + endif end select end function tNode_asList @@ -340,14 +352,19 @@ end function tNode_asList !-------------------------------------------------------------------------------------------------- function tNode_asDict(self) result(dict) - class(tNode), intent(in), target :: self - class(tDict), pointer :: dict + class(tNode), intent(in), target :: self + class(tDict), pointer :: dict select type(self) class is(tDict) dict => self class default - call IO_error(706,ext_msg='Expected "dict"') + write(6,'(a)') self%asFormattedString() + if(self%isScalar()) then + call IO_error(706,ext_msg='Expected "dict", found "scalar"') + else + call IO_error(706,ext_msg='Expected "dict", found "list"') + endif end select end function tNode_asDict @@ -444,7 +461,7 @@ function tNode_get_byIndex_asFloat(self,i) result(nodeAsFloat) type(tScalar), pointer :: scalar node => self%get(i) - scalar => node%asScalar() + scalar => node%asScalar(self) nodeAsFloat = scalar%asFloat() end function tNode_get_byIndex_asFloat @@ -463,7 +480,7 @@ function tNode_get_byIndex_asInt(self,i) result(nodeAsInt) type(tScalar), pointer :: scalar node => self%get(i) - scalar => node%asScalar() + scalar => node%asScalar(self) nodeAsInt = scalar%asInt() end function tNode_get_byIndex_asInt @@ -482,7 +499,7 @@ function tNode_get_byIndex_asBool(self,i) result(nodeAsBool) type(tScalar), pointer :: scalar node => self%get(i) - scalar => node%asScalar() + scalar => node%asScalar(self) nodeAsBool = scalar%asBool() end function tNode_get_byIndex_asBool @@ -501,7 +518,7 @@ function tNode_get_byIndex_asString(self,i) result(nodeAsString) type(tScalar), pointer :: scalar node => self%get(i) - scalar => node%asScalar() + scalar => node%asScalar(self) nodeAsString = scalar%asString() end function tNode_get_byIndex_asString @@ -520,7 +537,7 @@ function tNode_get_byIndex_asFloats(self,i) result(nodeAsFloats) class(tList), pointer :: list node => self%get(i) - list => node%asList() + list => node%asList(self) nodeAsFloats = list%asFloats() end function tNode_get_byIndex_asFloats @@ -539,7 +556,7 @@ function tNode_get_byIndex_asInts(self,i) result(nodeAsInts) class(tList), pointer :: list node => self%get(i) - list => node%asList() + list => node%asList(self) nodeAsInts = list%asInts() end function tNode_get_byIndex_asInts @@ -558,7 +575,7 @@ function tNode_get_byIndex_asBools(self,i) result(nodeAsBools) class(tList), pointer :: list node => self%get(i) - list => node%asList() + list => node%asList(self) nodeAsBools = list%asBools() end function tNode_get_byIndex_asBools @@ -577,7 +594,7 @@ function tNode_get_byIndex_asStrings(self,i) result(nodeAsStrings) type(tList), pointer :: list node => self%get(i) - list => node%asList() + list => node%asList(self) nodeAsStrings = list%asStrings() end function tNode_get_byIndex_asStrings @@ -699,10 +716,11 @@ function tNode_get_byKey_asFloat(self,k,defaultVal) result(nodeAsFloat) class(tNode), pointer :: node type(tScalar), pointer :: scalar + character(len=:), allocatable :: str if(self%contains(k)) then node => self%get(k) - scalar => node%asScalar() + scalar => node%asScalar(self) nodeAsFloat = scalar%asFloat() elseif(present(defaultVal)) then nodeAsFloat = defaultVal @@ -728,7 +746,7 @@ function tNode_get_byKey_asInt(self,k,defaultVal) result(nodeAsInt) if(self%contains(k)) then node => self%get(k) - scalar => node%asScalar() + scalar => node%asScalar(self) nodeAsInt = scalar%asInt() elseif(present(defaultVal)) then nodeAsInt = defaultVal @@ -754,7 +772,7 @@ function tNode_get_byKey_asBool(self,k,defaultVal) result(nodeAsBool) if(self%contains(k)) then node => self%get(k) - scalar => node%asScalar() + scalar => node%asScalar(self) nodeAsBool = scalar%asBool() elseif(present(defaultVal)) then nodeAsBool = defaultVal @@ -780,7 +798,7 @@ function tNode_get_byKey_asString(self,k,defaultVal) result(nodeAsString) if(self%contains(k)) then node => self%get(k) - scalar => node%asScalar() + scalar => node%asScalar(self) nodeAsString = scalar%asString() elseif(present(defaultVal)) then nodeAsString = defaultVal @@ -808,7 +826,7 @@ function tNode_get_byKey_asFloats(self,k,defaultVal,requiredSize) result(nodeAsF if(self%contains(k)) then node => self%get(k) - list => node%asList() + list => node%asList(self) nodeAsFloats = list%asFloats() elseif(present(defaultVal)) then nodeAsFloats = defaultVal @@ -839,7 +857,7 @@ function tNode_get_byKey_asInts(self,k,defaultVal,requiredSize) result(nodeAsInt if(self%contains(k)) then node => self%get(k) - list => node%asList() + list => node%asList(self) nodeAsInts = list%asInts() elseif(present(defaultVal)) then nodeAsInts = defaultVal @@ -869,7 +887,7 @@ function tNode_get_byKey_asBools(self,k,defaultVal) result(nodeAsBools) if(self%contains(k)) then node => self%get(k) - list => node%asList() + list => node%asList(self) nodeAsBools = list%asBools() elseif(present(defaultVal)) then nodeAsBools = defaultVal @@ -895,7 +913,7 @@ function tNode_get_byKey_asStrings(self,k,defaultVal) result(nodeAsStrings) if(self%contains(k)) then node => self%get(k) - list => node%asList() + list => node%asList(self) nodeAsStrings = list%asStrings() elseif(present(defaultVal)) then nodeAsStrings = defaultVal From c0620037a166c3bfbf4428a58063cdc43bbab6e7 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Sat, 27 Feb 2021 13:14:53 -0500 Subject: [PATCH 002/219] simplified tNode_get_byKey_asIndex and tNode_getKey_byIndex; syntax polishing --- src/YAML_types.f90 | 74 ++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 42 deletions(-) diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index 92e2a41ba..342440b34 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -72,7 +72,7 @@ module YAML_types getKey => tNode_getKey_byIndex procedure :: & contains => tNode_contains - + generic :: & get => tNode_get_byIndex, & tNode_get_byKey @@ -157,7 +157,7 @@ module YAML_types emptyDict type(tList), target, public :: & emptyList - + abstract interface recursive function asFormattedString(self,indent) @@ -179,7 +179,7 @@ module YAML_types public :: & YAML_types_init, & - output_asStrings, & !ToDo: Hack for GNU. Remove later + output_asStrings, & !ToDo: Hack for GNU. Remove later assignment(=) contains @@ -435,13 +435,12 @@ function tNode_get_byIndex(self,i) result(node) integer :: j self_ => self%asList() + item => self_%first + if(i < 1 .or. i > self_%length) call IO_error(150,ext_msg='tNode_get_byIndex') - j = 1 - item => self_%first - do while(j item%next - j = j + 1 enddo node => item%node @@ -615,14 +614,10 @@ function tNode_getKey_byIndex(self,i) result(key) dict => self%asDict() item => dict%first - do j = 1, dict%length - if(j == i) then - key = item%key - exit - else - item => item%next - endif + do j = 1, min(i,dict%length)-1 + item => item%next enddo + key = item%key end function tNode_getKey_byIndex @@ -630,7 +625,7 @@ end function tNode_getKey_byIndex !------------------------------------------------------------------------------------------------- !> @brief Checks if a given key/item is present in the dict/list !------------------------------------------------------------------------------------------------- -function tNode_contains(self,k) result(exists) +function tNode_contains(self,k) result(exists) class(tNode), intent(in), target :: self character(len=*), intent(in) :: k @@ -641,18 +636,18 @@ function tNode_contains(self,k) result(exists) type(tDict), pointer :: dict exists = .false. - if(self%isDict()) then + if (self%isDict()) then dict => self%asDict() do j=1, dict%length - if(dict%getKey(j) == k) then + if (dict%getKey(j) == k) then exists = .true. return endif enddo - elseif(self%isList()) then + elseif (self%isList()) then list => self%asList() - do j =1, list%length - if(list%get_asString(j) == k) then + do j=1, list%length + if (list%get_asString(j) == k) then exists = .true. return endif @@ -681,7 +676,7 @@ function tNode_get_byKey(self,k,defaultVal) result(node) found = present(defaultVal) if(found) node => defaultVal - + self_ => self%asDict() j = 1 @@ -694,7 +689,7 @@ function tNode_get_byKey(self,k,defaultVal) result(node) item => item%next j = j + 1 enddo - + if (.not. found) then call IO_error(143,ext_msg=k) else @@ -911,11 +906,11 @@ function tNode_get_byKey_asStrings(self,k,defaultVal) result(nodeAsStrings) class(tNode), pointer :: node type(tList), pointer :: list - if(self%contains(k)) then + if (self%contains(k)) then node => self%get(k) list => node%asList(self) nodeAsStrings = list%asStrings() - elseif(present(defaultVal)) then + elseif (present(defaultVal)) then nodeAsStrings = defaultVal else call IO_error(143,ext_msg=k) @@ -943,7 +938,7 @@ function output_asStrings(self) result(output) !ToDo: SR: Rem end function output_asStrings - + !-------------------------------------------------------------------------------------------------- !> @brief Returns the index of a key in a dictionary @@ -954,25 +949,20 @@ function tNode_get_byKey_asIndex(self,key) result(keyIndex) character(len=*), intent(in) :: key integer :: keyIndex - integer :: i type(tDict), pointer :: dict type(tItem), pointer :: item dict => self%asDict() item => dict%first - keyIndex = -1 - do i = 1, dict%length - if(key == item%key) then - keyIndex = i - exit - else - item => item%next - endif + keyIndex = 1 + do while (associated(item%next) .and. item%key /= key) + item => item%next + keyIndex = keyIndex+1 enddo - if(keyIndex == -1) call IO_error(140,ext_msg=key) + if (item%key /= key) call IO_error(140,ext_msg=key) + - end function tNode_get_byKey_asIndex @@ -1003,7 +993,7 @@ recursive function tList_asFormattedString(self,indent) result(str) integer :: i, indent_ str = '' - if(present(indent)) then + if (present(indent)) then indent_ = indent else indent_ = 0 @@ -1011,7 +1001,7 @@ recursive function tList_asFormattedString(self,indent) result(str) item => self%first do i = 1, self%length - if(i /= 1) str = str//repeat(' ',indent_) + if (i /= 1) str = str//repeat(' ',indent_) str = str//'- '//item%node%asFormattedString(indent_+2) item => item%next end do @@ -1032,7 +1022,7 @@ recursive function tDict_asFormattedString(self,indent) result(str) integer :: i, indent_ str = '' - if(present(indent)) then + if (present(indent)) then indent_ = indent else indent_ = 0 @@ -1040,7 +1030,7 @@ recursive function tDict_asFormattedString(self,indent) result(str) item => self%first do i = 1, self%length - if(i /= 1) str = str//repeat(' ',indent_) + if (i /= 1) str = str//repeat(' ',indent_) select type(node_1 =>item%node) class is(tScalar) str = str//trim(item%key)//': '//item%node%asFormattedString(indent_+len_trim(item%key)+2) @@ -1254,7 +1244,7 @@ subroutine tDict_set(self,key,node) if (item%key == key) exit item => item%next end do searchExisting - if (.not. item%key == key) then + if (item%key /= key) then allocate(item%next) item => item%next self%length = self%length + 1 @@ -1288,7 +1278,7 @@ recursive subroutine tItem_finalize(self) type(tItem),intent(inout) :: self deallocate(self%node) - if(associated(self%next)) deallocate(self%next) + if (associated(self%next)) deallocate(self%next) end subroutine tItem_finalize From fd24c9c2a193972ea17e94ba848d87d2aeb43028 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Sat, 27 Feb 2021 13:22:46 -0500 Subject: [PATCH 003/219] simplified tNode_get_byKey_asIndex and tNode_getKey_byIndex==>get_byIndex_asKey; syntax polishing --- src/YAML_types.f90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index 342440b34..7a741a5c8 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -67,9 +67,9 @@ module YAML_types procedure :: & tNode_get_byKey_asStrings => tNode_get_byKey_asStrings procedure :: & - getIndex => tNode_get_byKey_asIndex + getKey => tNode_get_byIndex_asKey procedure :: & - getKey => tNode_getKey_byIndex + getIndex => tNode_get_byKey_asIndex procedure :: & contains => tNode_contains @@ -602,7 +602,7 @@ end function tNode_get_byIndex_asStrings !-------------------------------------------------------------------------------------------------- !> @brief Returns the key in a dictionary as a string !-------------------------------------------------------------------------------------------------- -function tNode_getKey_byIndex(self,i) result(key) +function tNode_get_byIndex_asKey(self,i) result(key) class(tNode), intent(in), target :: self integer, intent(in) :: i @@ -619,7 +619,7 @@ function tNode_getKey_byIndex(self,i) result(key) enddo key = item%key -end function tNode_getKey_byIndex +end function tNode_get_byIndex_asKey !------------------------------------------------------------------------------------------------- From f3a2c49b3998146f9caf38f02373da44e18a41be Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Mon, 1 Mar 2021 19:03:50 +0100 Subject: [PATCH 004/219] read in 2d arrays in yaml --- src/YAML_types.f90 | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index b71261d9c..77b683acb 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -72,6 +72,8 @@ module YAML_types getKey => tNode_getKey_byIndex procedure :: & contains => tNode_contains + procedure :: & + get_table_asFloats => tNode_get_byKey_as2dFloats generic :: & get => tNode_get_byIndex, & @@ -823,6 +825,45 @@ function tNode_get_byKey_asFloats(self,k,defaultVal,requiredSize) result(nodeAsF end function tNode_get_byKey_asFloats +!-------------------------------------------------------------------------------------------------- +!> @brief Access by key and convert to float array +!-------------------------------------------------------------------------------------------------- +function tNode_get_byKey_as2dFloats(self,k) result(nodeAs2dFloats) + + class(tNode), intent(in), target :: self + character(len=*), intent(in) :: k + + real(pReal), dimension(:,:), allocatable :: nodeAs2dFloats + + class(tNode), pointer :: node,node_ + type(tList), pointer :: row_list,column_list + integer :: i,j + + + if(self%contains(k)) then + node => self%get(k) + row_list => node%asList() + node_ => row_list%get(1) + column_list => node_%asList() + allocate(nodeAs2dFloats(row_list%length,column_list%length),source=0.0_pReal) + else + call IO_error(143,ext_msg=k) + endif + + node => self%get(k) + row_list => node%asList() + do i=1,row_list%length + node_ => row_list%get(i) + column_list => node_%asList() + do j=1,column_list%length + nodeAs2dFloats(i,j) = column_list%get_asFloat(j) + enddo + enddo + + +end function tNode_get_byKey_as2dFloats + + !-------------------------------------------------------------------------------------------------- !> @brief Access by key and convert to int array !-------------------------------------------------------------------------------------------------- From 357fd81be4257fdc0172a9ee6ea74027547e2ab8 Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Tue, 2 Mar 2021 16:14:33 +0100 Subject: [PATCH 005/219] read in 2d float arrays in yaml test added too --- src/YAML_types.f90 | 94 +++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index 77b683acb..165f31d6a 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -73,7 +73,7 @@ module YAML_types procedure :: & contains => tNode_contains procedure :: & - get_table_asFloats => tNode_get_byKey_as2dFloats + get_table_asFloats => tNode_get_byKey_as2dFloats !SR: Name needs to change generic :: & get => tNode_get_byIndex, & @@ -129,7 +129,9 @@ module YAML_types procedure :: asFormattedString => tList_asFormattedString procedure :: append => tList_append procedure :: & - asFloats => tList_asFloats + asFloats => tList_asFloats + procedure :: & + as2dFloats => tList_as2dFloats procedure :: & asInts => tList_asInts procedure :: & @@ -203,9 +205,11 @@ end subroutine YAML_types_init !-------------------------------------------------------------------------------------------------- subroutine selfTest - class(tNode), pointer :: s1,s2 + class(tNode), pointer :: s1,s2,s3,s4 allocate(tScalar::s1) allocate(tScalar::s2) + allocate(tScalar::s3) + allocate(tScalar::s4) select type(s1) class is(tScalar) s1 = '1' @@ -217,7 +221,9 @@ subroutine selfTest end select block - class(tNode), pointer :: l1, l2, n + class(tNode), pointer :: l1, l2, l3, n + real(pReal), allocatable, dimension(:,:) :: x + select type(s1) class is(tScalar) s1 = '2' @@ -228,6 +234,17 @@ subroutine selfTest s2 = '3' endselect + select type(s3) + class is(tScalar) + s3 = '4' + endselect + + select type(s4) + class is(tScalar) + s4 = '5' + endselect + + allocate(tList::l1) select type(l1) class is(tList) @@ -240,12 +257,24 @@ subroutine selfTest if(dNeq(n%get_asFloat(2),3.0_pReal)) error stop 'byIndex_asFloat' endselect + allocate(tList::l3) + select type(l3) + class is(tList) + call l3%append(s3) + call l3%append(s4) + endselect + allocate(tList::l2) select type(l2) class is(tList) call l2%append(l1) if(any(l2%get_asInts(1) /= [2,3])) error stop 'byIndex_asInts' if(any(dNeq(l2%get_asFloats(1),[2.0_pReal,3.0_pReal]))) error stop 'byIndex_asFloats' + call l2%append(l3) + x = l2%as2dFloats() + if(x(2,1)/= 4.0_pReal) error stop 'byKey_as2dFloats' + if(any(dNeq(pack(l2%as2dFloats(),.true.),& + [2.0_pReal,4.0_pReal,3.0_pReal,5.0_pReal]))) error stop 'byKey_as2dFloats' n => l2 end select deallocate(n) @@ -826,40 +855,28 @@ end function tNode_get_byKey_asFloats !-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to float array +!> @brief Access by key and convert to 2D float array !-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_as2dFloats(self,k) result(nodeAs2dFloats) +function tNode_get_byKey_as2dFloats(self,k,defaultVal) result(nodeAs2dFloats) - class(tNode), intent(in), target :: self - character(len=*), intent(in) :: k + class(tNode), intent(in), target :: self + character(len=*), intent(in) :: k + real(pReal), intent(in), dimension(:,:), optional :: defaultVal real(pReal), dimension(:,:), allocatable :: nodeAs2dFloats - class(tNode), pointer :: node,node_ - type(tList), pointer :: row_list,column_list - integer :: i,j - + class(tNode), pointer :: node + type(tList), pointer :: rows if(self%contains(k)) then node => self%get(k) - row_list => node%asList() - node_ => row_list%get(1) - column_list => node_%asList() - allocate(nodeAs2dFloats(row_list%length,column_list%length),source=0.0_pReal) + rows => node%asList() + nodeAs2dFloats = rows%as2dFloats() + elseif(present(defaultVal)) then + nodeAs2dFloats = defaultVal else call IO_error(143,ext_msg=k) endif - - node => self%get(k) - row_list => node%asList() - do i=1,row_list%length - node_ => row_list%get(i) - column_list => node_%asList() - do j=1,column_list%length - nodeAs2dFloats(i,j) = column_list%get_asFloat(j) - enddo - enddo - end function tNode_get_byKey_as2dFloats @@ -1151,6 +1168,29 @@ function tList_asFloats(self) end function tList_asFloats +!-------------------------------------------------------------------------------------------------- +!> @brief Convert to 2D float array +!-------------------------------------------------------------------------------------------------- +function tList_as2dFloats(self) + + class(tList), intent(in), target :: self + real(pReal), dimension(:,:), allocatable :: tList_as2dFloats + + integer :: i + class(tNode), pointer :: row + type(tList), pointer :: row_data + + row => self%get(1) !SR: some interface called 'shape' may be used? + row_data => row%asList() + allocate(tList_as2dFloats(row%length,row_data%length),source=0.0_pReal) + + do i=1,self%length + tList_as2dFloats(i,:) = self%get_asFloats(i) + enddo + +end function tList_as2dFloats + + !-------------------------------------------------------------------------------------------------- !> @brief Convert to int array !-------------------------------------------------------------------------------------------------- From 5d51da11e527615c5a7f3adfdf9ff76c2e83ac3a Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Tue, 2 Mar 2021 18:41:26 +0100 Subject: [PATCH 006/219] trying new structure to have better yaml error messages --- src/YAML_types.f90 | 175 +++++++++++++++++++++++++++++++-------------- 1 file changed, 123 insertions(+), 52 deletions(-) diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index b71261d9c..a6b9d9740 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -310,8 +310,6 @@ function tNode_asScalar(self) result(scalar) select type(self) class is(tScalar) scalar => self - class default - call IO_error(706,ext_msg='Expected "scalar"') end select end function tNode_asScalar @@ -328,8 +326,6 @@ function tNode_asList(self) result(list) select type(self) class is(tList) list => self - class default - call IO_error(706,ext_msg='Expected "list"') end select end function tNode_asList @@ -346,8 +342,6 @@ function tNode_asDict(self) result(dict) select type(self) class is(tDict) dict => self - class default - call IO_error(706,ext_msg='Expected "dict"') end select end function tNode_asDict @@ -417,7 +411,12 @@ function tNode_get_byIndex(self,i) result(node) class(tItem), pointer :: item integer :: j - self_ => self%asList() + if(self%isList()) then + self_ => self%asList() + else + call IO_error(706,ext_msg='Expected List') + endif + if(i < 1 .or. i > self_%length) call IO_error(150,ext_msg='tNode_get_byIndex') j = 1 @@ -444,8 +443,12 @@ function tNode_get_byIndex_asFloat(self,i) result(nodeAsFloat) type(tScalar), pointer :: scalar node => self%get(i) - scalar => node%asScalar() - nodeAsFloat = scalar%asFloat() + if(node%isScalar()) then + scalar => node%asScalar() + nodeAsFloat = scalar%asFloat() + else + call IO_error(706,ext_msg='Expected Scalar') + endif end function tNode_get_byIndex_asFloat @@ -463,8 +466,12 @@ function tNode_get_byIndex_asInt(self,i) result(nodeAsInt) type(tScalar), pointer :: scalar node => self%get(i) - scalar => node%asScalar() - nodeAsInt = scalar%asInt() + if(node%isScalar()) then + scalar => node%asScalar() + nodeAsInt = scalar%asInt() + else + call IO_error(706,ext_msg='Expected Scalar') + endif end function tNode_get_byIndex_asInt @@ -482,8 +489,12 @@ function tNode_get_byIndex_asBool(self,i) result(nodeAsBool) type(tScalar), pointer :: scalar node => self%get(i) - scalar => node%asScalar() - nodeAsBool = scalar%asBool() + if(node%isScalar()) then + scalar => node%asScalar() + nodeAsBool = scalar%asBool() + else + call IO_error(706,ext_msg='Expected Scalar') + endif end function tNode_get_byIndex_asBool @@ -501,8 +512,12 @@ function tNode_get_byIndex_asString(self,i) result(nodeAsString) type(tScalar), pointer :: scalar node => self%get(i) - scalar => node%asScalar() - nodeAsString = scalar%asString() + if(node%isScalar()) then + scalar => node%asScalar() + nodeAsString = scalar%asString() + else + call IO_error(706,ext_msg='Expected Scalar') + endif end function tNode_get_byIndex_asString @@ -520,8 +535,12 @@ function tNode_get_byIndex_asFloats(self,i) result(nodeAsFloats) class(tList), pointer :: list node => self%get(i) - list => node%asList() - nodeAsFloats = list%asFloats() + if(node%isList()) then + list => node%asList() + nodeAsFloats = list%asFloats() + else + call IO_error(706,ext_msg='Expected list') + endif end function tNode_get_byIndex_asFloats @@ -539,8 +558,12 @@ function tNode_get_byIndex_asInts(self,i) result(nodeAsInts) class(tList), pointer :: list node => self%get(i) - list => node%asList() - nodeAsInts = list%asInts() + if(node%isList()) then + list => node%asList() + nodeAsInts = list%asInts() + else + call IO_error(706,ext_msg='Expected list') + endif end function tNode_get_byIndex_asInts @@ -558,8 +581,12 @@ function tNode_get_byIndex_asBools(self,i) result(nodeAsBools) class(tList), pointer :: list node => self%get(i) - list => node%asList() - nodeAsBools = list%asBools() + if(node%isList()) then + list => node%asList() + nodeAsBools = list%asBools() + else + call IO_error(706,ext_msg='Expected list') + endif end function tNode_get_byIndex_asBools @@ -577,8 +604,12 @@ function tNode_get_byIndex_asStrings(self,i) result(nodeAsStrings) type(tList), pointer :: list node => self%get(i) - list => node%asList() - nodeAsStrings = list%asStrings() + if(node%isList()) then + list => node%asList() + nodeAsStrings = list%asStrings() + else + call IO_error(706,ext_msg='Expected list') + endif end function tNode_get_byIndex_asStrings @@ -596,16 +627,20 @@ function tNode_getKey_byIndex(self,i) result(key) type(tDict), pointer :: dict type(tItem), pointer :: item - dict => self%asDict() - item => dict%first - do j = 1, dict%length - if(j == i) then - key = item%key - exit - else - item => item%next - endif - enddo + if(self%isDict()) then + dict => self%asDict() + item => dict%first + do j = 1, dict%length + if(j == i) then + key = item%key + exit + else + item => item%next + endif + enddo + else + call IO_error(706,ext_msg='Expected dict') + endif end function tNode_getKey_byIndex @@ -641,7 +676,7 @@ function tNode_contains(self,k) result(exists) endif enddo else - call IO_error(706,ext_msg='Expected "list" or "dict"') + call IO_error(706,ext_msg='Expected "list" or "dict"') endif end function tNode_contains @@ -664,8 +699,12 @@ function tNode_get_byKey(self,k,defaultVal) result(node) found = present(defaultVal) if(found) node => defaultVal - - self_ => self%asDict() + + if(self%isDict()) then + self_ => self%asDict() + else + call IO_error(706,ext_msg='Expected Dict for key '//k) + endif j = 1 item => self_%first @@ -702,8 +741,12 @@ function tNode_get_byKey_asFloat(self,k,defaultVal) result(nodeAsFloat) if(self%contains(k)) then node => self%get(k) - scalar => node%asScalar() - nodeAsFloat = scalar%asFloat() + if(node%isScalar()) then + scalar => node%asScalar() + nodeAsFloat = scalar%asFloat() + else + call IO_error(706,ext_msg='Expected Scalar for key '//k) + endif elseif(present(defaultVal)) then nodeAsFloat = defaultVal else @@ -728,8 +771,12 @@ function tNode_get_byKey_asInt(self,k,defaultVal) result(nodeAsInt) if(self%contains(k)) then node => self%get(k) - scalar => node%asScalar() - nodeAsInt = scalar%asInt() + if(node%isScalar()) then + scalar => node%asScalar() + nodeAsInt = scalar%asInt() + else + call IO_error(706,ext_msg='Expected Scalar for key '//k) + endif elseif(present(defaultVal)) then nodeAsInt = defaultVal else @@ -754,8 +801,12 @@ function tNode_get_byKey_asBool(self,k,defaultVal) result(nodeAsBool) if(self%contains(k)) then node => self%get(k) - scalar => node%asScalar() - nodeAsBool = scalar%asBool() + if(node%isScalar()) then + scalar => node%asScalar() + nodeAsBool = scalar%asBool() + else + call IO_error(706,ext_msg='Expected Scalar for key '//k) + endif elseif(present(defaultVal)) then nodeAsBool = defaultVal else @@ -780,8 +831,12 @@ function tNode_get_byKey_asString(self,k,defaultVal) result(nodeAsString) if(self%contains(k)) then node => self%get(k) - scalar => node%asScalar() - nodeAsString = scalar%asString() + if(node%isScalar()) then + scalar => node%asScalar() + nodeAsString = scalar%asString() + else + call IO_error(706,ext_msg='Expected Scalar for key '//k) + endif elseif(present(defaultVal)) then nodeAsString = defaultVal else @@ -808,8 +863,12 @@ function tNode_get_byKey_asFloats(self,k,defaultVal,requiredSize) result(nodeAsF if(self%contains(k)) then node => self%get(k) - list => node%asList() - nodeAsFloats = list%asFloats() + if(node%isList()) then + list => node%asList() + nodeAsFloats = list%asFloats() + else + call IO_error(706,ext_msg='Expected list for key '//k) + endif elseif(present(defaultVal)) then nodeAsFloats = defaultVal else @@ -839,8 +898,12 @@ function tNode_get_byKey_asInts(self,k,defaultVal,requiredSize) result(nodeAsInt if(self%contains(k)) then node => self%get(k) - list => node%asList() - nodeAsInts = list%asInts() + if(node%isList()) then + list => node%asList() + nodeAsInts = list%asInts() + else + call IO_error(706,ext_msg='Expected list for key '//k) + endif elseif(present(defaultVal)) then nodeAsInts = defaultVal else @@ -869,8 +932,12 @@ function tNode_get_byKey_asBools(self,k,defaultVal) result(nodeAsBools) if(self%contains(k)) then node => self%get(k) - list => node%asList() - nodeAsBools = list%asBools() + if(node%isList())then + list => node%asList() + nodeAsBools = list%asBools() + else + call IO_error(706,ext_msg='Expected list for key '//k) + endif elseif(present(defaultVal)) then nodeAsBools = defaultVal else @@ -895,8 +962,12 @@ function tNode_get_byKey_asStrings(self,k,defaultVal) result(nodeAsStrings) if(self%contains(k)) then node => self%get(k) - list => node%asList() - nodeAsStrings = list%asStrings() + if(node%isList()) then + list => node%asList() + nodeAsStrings = list%asStrings() + else + call IO_error(706,ext_msg='Expected list for key '//k) + endif elseif(present(defaultVal)) then nodeAsStrings = defaultVal else From adcb24d2e1e5af2eae011cd77b0abbf234c6a7d9 Mon Sep 17 00:00:00 2001 From: Vitesh Shah Date: Wed, 10 Mar 2021 16:33:02 +0100 Subject: [PATCH 007/219] write data of average quantities non parallel --- src/grid/grid_mech_FEM.f90 | 12 ++++++------ src/grid/grid_mech_spectral_basic.f90 | 14 +++++++------- src/grid/grid_mech_spectral_polarisation.f90 | 12 ++++++------ 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index 609561c80..4bf2c6658 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -431,17 +431,17 @@ subroutine grid_mechanical_FEM_restartWrite fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','w') groupHandle = HDF5_addGroup(fileHandle,'solver') - call HDF5_write(groupHandle,P_aim, 'P_aim') - call HDF5_write(groupHandle,F_aim, 'F_aim') - call HDF5_write(groupHandle,F_aim_lastInc,'F_aim_lastInc') - call HDF5_write(groupHandle,F_aimDot, 'F_aimDot') + call HDF5_write(groupHandle,P_aim, 'P_aim',.false.) + call HDF5_write(groupHandle,F_aim, 'F_aim',.false.) + call HDF5_write(groupHandle,F_aim_lastInc,'F_aim_lastInc',.false.) + call HDF5_write(groupHandle,F_aimDot, 'F_aimDot',.false.) call HDF5_write(groupHandle,F, 'F') call HDF5_write(groupHandle,F_lastInc, 'F_lastInc') call HDF5_write(groupHandle,u_current, 'u') call HDF5_write(groupHandle,u_lastInc, 'u_lastInc') - call HDF5_write(groupHandle,C_volAvg, 'C_volAvg') - call HDF5_write(groupHandle,C_volAvgLastInc,'C_volAvgLastInc') + call HDF5_write(groupHandle,C_volAvg, 'C_volAvg',.false.) + call HDF5_write(groupHandle,C_volAvgLastInc,'C_volAvgLastInc',.false.) call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index faf58c85e..8249a2503 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -370,16 +370,16 @@ subroutine grid_mechanical_spectral_basic_restartWrite fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','w') groupHandle = HDF5_addGroup(fileHandle,'solver') - call HDF5_write(groupHandle,P_aim, 'P_aim') - call HDF5_write(groupHandle,F_aim, 'F_aim') - call HDF5_write(groupHandle,F_aim_lastInc,'F_aim_lastInc') - call HDF5_write(groupHandle,F_aimDot, 'F_aimDot') + call HDF5_write(groupHandle,P_aim, 'P_aim',.false.) + call HDF5_write(groupHandle,F_aim, 'F_aim',.false.) + call HDF5_write(groupHandle,F_aim_lastInc,'F_aim_lastInc',.false.) + call HDF5_write(groupHandle,F_aimDot, 'F_aimDot',.false.) call HDF5_write(groupHandle,F, 'F') call HDF5_write(groupHandle,F_lastInc, 'F_lastInc') - call HDF5_write(groupHandle,C_volAvg, 'C_volAvg') - call HDF5_write(groupHandle,C_volAvgLastInc,'C_volAvgLastInc') - call HDF5_write(groupHandle,C_minMaxAvg, 'C_minMaxAvg') + call HDF5_write(groupHandle,C_volAvg, 'C_volAvg',.false.) + call HDF5_write(groupHandle,C_volAvgLastInc,'C_volAvgLastInc',.false.) + call HDF5_write(groupHandle,C_minMaxAvg, 'C_minMaxAvg',.false.) call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index 31f69b4c5..676252e6d 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -426,17 +426,17 @@ subroutine grid_mechanical_spectral_polarisation_restartWrite fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','w') groupHandle = HDF5_addGroup(fileHandle,'solver') - call HDF5_write(groupHandle,F_aim, 'P_aim') - call HDF5_write(groupHandle,F_aim, 'F_aim') - call HDF5_write(groupHandle,F_aim_lastInc,'F_aim_lastInc') - call HDF5_write(groupHandle,F_aimDot, 'F_aimDot') + call HDF5_write(groupHandle,F_aim, 'P_aim',.false.) + call HDF5_write(groupHandle,F_aim, 'F_aim',.false.) + call HDF5_write(groupHandle,F_aim_lastInc,'F_aim_lastInc',.false.) + call HDF5_write(groupHandle,F_aimDot, 'F_aimDot',.false.) call HDF5_write(groupHandle,F, 'F') call HDF5_write(groupHandle,F_lastInc, 'F_lastInc') call HDF5_write(groupHandle,F_tau, 'F_tau') call HDF5_write(groupHandle,F_tau_lastInc,'F_tau_lastInc') - call HDF5_write(groupHandle,C_volAvg, 'C_volAvg') - call HDF5_write(groupHandle,C_volAvgLastInc,'C_volAvgLastInc') + call HDF5_write(groupHandle,C_volAvg, 'C_volAvg',.false.) + call HDF5_write(groupHandle,C_volAvgLastInc,'C_volAvgLastInc',.false.) call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) From ce91537b0fe2ea1e2d95253dec68f9e42a894040 Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Thu, 11 Mar 2021 18:00:07 +0100 Subject: [PATCH 008/219] get_asXXs --> get_as1dXX --- src/YAML_types.f90 | 250 +++++++++--------- src/grid/DAMASK_grid.f90 | 2 +- src/homogenization_damage.f90 | 4 +- src/homogenization_mechanical_RGC.f90 | 10 +- src/homogenization_thermal.f90 | 4 +- src/phase_damage_anisobrittle.f90 | 10 +- src/phase_damage_anisoductile.f90 | 8 +- src/phase_damage_isobrittle.f90 | 4 +- src/phase_damage_isoductile.f90 | 4 +- src/phase_mechanical.f90 | 6 +- ...hase_mechanical_eigen_slipplaneopening.f90 | 4 +- ...hase_mechanical_eigen_thermalexpansion.f90 | 6 +- ...phase_mechanical_plastic_dislotungsten.f90 | 36 +-- src/phase_mechanical_plastic_dislotwin.f90 | 56 ++-- src/phase_mechanical_plastic_isotropic.f90 | 4 +- ...phase_mechanical_plastic_kinehardening.f90 | 24 +- src/phase_mechanical_plastic_nonlocal.f90 | 34 +-- ...phase_mechanical_plastic_phenopowerlaw.f90 | 26 +- src/phase_thermal_externalheat.f90 | 4 +- 19 files changed, 248 insertions(+), 248 deletions(-) diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index 8043d828b..b821db34f 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -31,41 +31,41 @@ module YAML_types procedure :: & isDict => tNode_isDict procedure :: & - tNode_get_byIndex => tNode_get_byIndex + tNode_get_byIndex => tNode_get_byIndex procedure :: & - tNode_get_byIndex_asFloat => tNode_get_byIndex_asFloat + tNode_get_byIndex_asFloat => tNode_get_byIndex_asFloat procedure :: & - tNode_get_byIndex_asFloats => tNode_get_byIndex_asFloats + tNode_get_byIndex_as1dFloat => tNode_get_byIndex_as1dFloat procedure :: & - tNode_get_byIndex_asInt => tNode_get_byIndex_asInt + tNode_get_byIndex_asInt => tNode_get_byIndex_asInt procedure :: & - tNode_get_byIndex_asInts => tNode_get_byIndex_asInts + tNode_get_byIndex_as1dInt => tNode_get_byIndex_as1dInt procedure :: & - tNode_get_byIndex_asBool => tNode_get_byIndex_asBool + tNode_get_byIndex_asBool => tNode_get_byIndex_asBool procedure :: & - tNode_get_byIndex_asBools => tNode_get_byIndex_asBools + tNode_get_byIndex_as1dBool => tNode_get_byIndex_as1dBool procedure :: & - tNode_get_byIndex_asString => tNode_get_byIndex_asString + tNode_get_byIndex_asString => tNode_get_byIndex_asString procedure :: & - tNode_get_byIndex_asStrings => tNode_get_byIndex_asStrings + tNode_get_byIndex_as1dString => tNode_get_byIndex_as1dString procedure :: & - tNode_get_byKey => tNode_get_byKey + tNode_get_byKey => tNode_get_byKey procedure :: & - tNode_get_byKey_asFloat => tNode_get_byKey_asFloat + tNode_get_byKey_asFloat => tNode_get_byKey_asFloat procedure :: & - tNode_get_byKey_asFloats => tNode_get_byKey_asFloats + tNode_get_byKey_as1dFloat => tNode_get_byKey_as1dFloat procedure :: & - tNode_get_byKey_asInt => tNode_get_byKey_asInt + tNode_get_byKey_asInt => tNode_get_byKey_asInt procedure :: & - tNode_get_byKey_asInts => tNode_get_byKey_asInts + tNode_get_byKey_as1dInt => tNode_get_byKey_as1dInt procedure :: & tNode_get_byKey_asBool => tNode_get_byKey_asBool procedure :: & - tNode_get_byKey_asBools => tNode_get_byKey_asBools + tNode_get_byKey_as1dBool => tNode_get_byKey_as1dBool procedure :: & tNode_get_byKey_asString => tNode_get_byKey_asString procedure :: & - tNode_get_byKey_asStrings => tNode_get_byKey_asStrings + tNode_get_byKey_as1dString => tNode_get_byKey_as1dString procedure :: & getIndex => tNode_get_byKey_asIndex procedure :: & @@ -73,35 +73,35 @@ module YAML_types procedure :: & contains => tNode_contains procedure :: & - get_table_asFloats => tNode_get_byKey_as2dFloats !SR: Name needs to change + get_as2dFloat => tNode_get_byKey_as2dFloat generic :: & - get => tNode_get_byIndex, & - tNode_get_byKey + get => tNode_get_byIndex, & + tNode_get_byKey generic :: & - get_asFloat => tNode_get_byIndex_asFloat, & - tNode_get_byKey_asFloat + get_asFloat => tNode_get_byIndex_asFloat, & + tNode_get_byKey_asFloat generic :: & - get_asFloats => tNode_get_byIndex_asFloats, & - tNode_get_byKey_asFloats + get_as1dFloat => tNode_get_byIndex_as1dFloat, & + tNode_get_byKey_as1dFloat generic :: & - get_asInt => tNode_get_byIndex_asInt, & - tNode_get_byKey_asInt + get_asInt => tNode_get_byIndex_asInt, & + tNode_get_byKey_asInt generic :: & - get_asInts => tNode_get_byIndex_asInts, & - tNode_get_byKey_asInts + get_as1dInt => tNode_get_byIndex_as1dInt, & + tNode_get_byKey_as1dInt generic :: & - get_asBool => tNode_get_byIndex_asBool, & - tNode_get_byKey_asBool + get_asBool => tNode_get_byIndex_asBool, & + tNode_get_byKey_asBool generic :: & - get_asBools => tNode_get_byIndex_asBools, & - tNode_get_byKey_asBools + get_as1dBool => tNode_get_byIndex_as1dBool, & + tNode_get_byKey_as1dBool generic :: & - get_asString => tNode_get_byIndex_asString, & - tNode_get_byKey_asString + get_asString => tNode_get_byIndex_asString, & + tNode_get_byKey_asString generic :: & - get_asStrings => tNode_get_byIndex_asStrings, & - tNode_get_byKey_asStrings + get_as1dString => tNode_get_byIndex_as1dString, & + tNode_get_byKey_as1dString end type tNode @@ -129,15 +129,15 @@ module YAML_types procedure :: asFormattedString => tList_asFormattedString procedure :: append => tList_append procedure :: & - asFloats => tList_asFloats + as1dFloat => tList_as1dFloat procedure :: & - as2dFloats => tList_as2dFloats + as2dFloat => tList_as2dFloat procedure :: & - asInts => tList_asInts + as1dInt => tList_as1dInt procedure :: & - asBools => tList_asBools + as1dBool => tList_as1dBool procedure :: & - asStrings => tList_asStrings + as1dString => tList_as1dString final :: tList_finalize end type tList @@ -183,7 +183,7 @@ module YAML_types public :: & YAML_types_init, & - output_asStrings, & !ToDo: Hack for GNU. Remove later + output_as1dString, & !ToDo: Hack for GNU. Remove later assignment(=) contains @@ -251,10 +251,10 @@ subroutine selfTest call l1%append(s1) call l1%append(s2) n => l1 - if (any(l1%asInts() /= [2,3])) error stop 'tList_asInts' - if (any(dNeq(l1%asFloats(),[2.0_pReal,3.0_pReal]))) error stop 'tList_asFloats' - if (n%get_asInt(1) /= 2) error stop 'byIndex_asInt' - if (dNeq(n%get_asFloat(2),3.0_pReal)) error stop 'byIndex_asFloat' + if (any(l1%as1dInt() /= [2,3])) error stop 'tList_as1dInt' + if (any(dNeq(l1%as1dFloat(),[2.0_pReal,3.0_pReal]))) error stop 'tList_as1dFloat' + if (n%get_asInt(1) /= 2) error stop 'byIndex_asInt' + if (dNeq(n%get_asFloat(2),3.0_pReal)) error stop 'byIndex_asFloat' endselect allocate(tList::l3) @@ -268,13 +268,13 @@ subroutine selfTest select type(l2) class is(tList) call l2%append(l1) - if(any(l2%get_asInts(1) /= [2,3])) error stop 'byIndex_asInts' - if(any(dNeq(l2%get_asFloats(1),[2.0_pReal,3.0_pReal]))) error stop 'byIndex_asFloats' + if(any(l2%get_as1dInt(1) /= [2,3])) error stop 'byIndex_as1dInt' + if(any(dNeq(l2%get_as1dFloat(1),[2.0_pReal,3.0_pReal]))) error stop 'byIndex_as1dFloat' call l2%append(l3) - x = l2%as2dFloats() - if(x(2,1)/= 4.0_pReal) error stop 'byKey_as2dFloats' - if(any(dNeq(pack(l2%as2dFloats(),.true.),& - [2.0_pReal,4.0_pReal,3.0_pReal,5.0_pReal]))) error stop 'byKey_as2dFloats' + x = l2%as2dFloat() + if(x(2,1)/= 4.0_pReal) error stop 'byKey_as2dFloat' + if(any(dNeq(pack(l2%as2dFloat(),.true.),& + [2.0_pReal,4.0_pReal,3.0_pReal,5.0_pReal]))) error stop 'byKey_as2dFloat' n => l2 end select deallocate(n) @@ -296,10 +296,10 @@ subroutine selfTest call l1%append(s2) n => l1 - if (any(l1%asBools() .neqv. [.true., .false.])) error stop 'tList_asBools' - if (any(l1%asStrings() /= ['true ','False'])) error stop 'tList_asStrings' - if (n%get_asBool(2)) error stop 'byIndex_asBool' - if (n%get_asString(1) /= 'true') error stop 'byIndex_asString' + if (any(l1%as1dBool() .neqv. [.true., .false.])) error stop 'tList_as1dBool' + if (any(l1%as1dString() /= ['true ','False'])) error stop 'tList_as1dString' + if (n%get_asBool(2)) error stop 'byIndex_asBool' + if (n%get_asString(1) /= 'true') error stop 'byIndex_asString' end block end subroutine selfTest @@ -541,77 +541,77 @@ end function tNode_get_byIndex_asString !-------------------------------------------------------------------------------------------------- !> @brief Access by index and convert to float array !-------------------------------------------------------------------------------------------------- -function tNode_get_byIndex_asFloats(self,i) result(nodeAsFloats) +function tNode_get_byIndex_as1dFloat(self,i) result(nodeAs1dFloat) class(tNode), intent(in), target :: self integer, intent(in) :: i - real(pReal), dimension(:), allocatable :: nodeAsFloats + real(pReal), dimension(:), allocatable :: nodeAs1dFloat class(tNode), pointer :: node class(tList), pointer :: list node => self%get(i) list => node%asList() - nodeAsFloats = list%asFloats() + nodeAs1dFloat = list%as1dFloat() -end function tNode_get_byIndex_asFloats +end function tNode_get_byIndex_as1dFloat !-------------------------------------------------------------------------------------------------- !> @brief Access by index and convert to int array !-------------------------------------------------------------------------------------------------- -function tNode_get_byIndex_asInts(self,i) result(nodeAsInts) +function tNode_get_byIndex_as1dInt(self,i) result(nodeAs1dInt) class(tNode), intent(in), target :: self integer, intent(in) :: i - integer, dimension(:), allocatable :: nodeAsInts + integer, dimension(:), allocatable :: nodeAs1dInt class(tNode), pointer :: node class(tList), pointer :: list node => self%get(i) list => node%asList() - nodeAsInts = list%asInts() + nodeAs1dInt = list%as1dInt() -end function tNode_get_byIndex_asInts +end function tNode_get_byIndex_as1dInt !-------------------------------------------------------------------------------------------------- !> @brief Access by index and convert to bool array !-------------------------------------------------------------------------------------------------- -function tNode_get_byIndex_asBools(self,i) result(nodeAsBools) +function tNode_get_byIndex_as1dBool(self,i) result(nodeAs1dBool) class(tNode), intent(in), target :: self integer, intent(in) :: i - logical, dimension(:), allocatable :: nodeAsBools + logical, dimension(:), allocatable :: nodeAs1dBool class(tNode), pointer :: node class(tList), pointer :: list node => self%get(i) list => node%asList() - nodeAsBools = list%asBools() + nodeAs1dBool = list%as1dBool() -end function tNode_get_byIndex_asBools +end function tNode_get_byIndex_as1dBool !-------------------------------------------------------------------------------------------------- !> @brief Access by index and convert to string array !-------------------------------------------------------------------------------------------------- -function tNode_get_byIndex_asStrings(self,i) result(nodeAsStrings) +function tNode_get_byIndex_as1dString(self,i) result(nodeAs1dString) class(tNode), intent(in), target :: self integer, intent(in) :: i - character(len=:), allocatable, dimension(:) :: nodeAsStrings + character(len=:), allocatable, dimension(:) :: nodeAs1dString class(tNode), pointer :: node type(tList), pointer :: list node => self%get(i) list => node%asList() - nodeAsStrings = list%asStrings() + nodeAs1dString = list%as1dString() -end function tNode_get_byIndex_asStrings +end function tNode_get_byIndex_as1dString !-------------------------------------------------------------------------------------------------- @@ -825,14 +825,14 @@ end function tNode_get_byKey_asString !-------------------------------------------------------------------------------------------------- !> @brief Access by key and convert to float array !-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_asFloats(self,k,defaultVal,requiredSize) result(nodeAsFloats) +function tNode_get_byKey_as1dFloat(self,k,defaultVal,requiredSize) result(nodeAs1dFloat) class(tNode), intent(in), target :: self character(len=*), intent(in) :: k real(pReal), intent(in), dimension(:), optional :: defaultVal integer, intent(in), optional :: requiredSize - real(pReal), dimension(:), allocatable :: nodeAsFloats + real(pReal), dimension(:), allocatable :: nodeAs1dFloat class(tNode), pointer :: node type(tList), pointer :: list @@ -840,30 +840,30 @@ function tNode_get_byKey_asFloats(self,k,defaultVal,requiredSize) result(nodeAsF if (self%contains(k)) then node => self%get(k) list => node%asList() - nodeAsFloats = list%asFloats() + nodeAs1dFloat = list%as1dFloat() elseif (present(defaultVal)) then - nodeAsFloats = defaultVal + nodeAs1dFloat = defaultVal else call IO_error(143,ext_msg=k) endif if (present(requiredSize)) then - if (requiredSize /= size(nodeAsFloats)) call IO_error(146,ext_msg=k) + if (requiredSize /= size(nodeAs1dFloat)) call IO_error(146,ext_msg=k) endif -end function tNode_get_byKey_asFloats +end function tNode_get_byKey_as1dFloat !-------------------------------------------------------------------------------------------------- !> @brief Access by key and convert to 2D float array !-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_as2dFloats(self,k,defaultVal) result(nodeAs2dFloats) +function tNode_get_byKey_as2dFloat(self,k,defaultVal) result(nodeAs2dFloat) class(tNode), intent(in), target :: self character(len=*), intent(in) :: k real(pReal), intent(in), dimension(:,:), optional :: defaultVal - real(pReal), dimension(:,:), allocatable :: nodeAs2dFloats + real(pReal), dimension(:,:), allocatable :: nodeAs2dFloat class(tNode), pointer :: node type(tList), pointer :: rows @@ -871,26 +871,26 @@ function tNode_get_byKey_as2dFloats(self,k,defaultVal) result(nodeAs2dFloats) if(self%contains(k)) then node => self%get(k) rows => node%asList() - nodeAs2dFloats = rows%as2dFloats() + nodeAs2dFloat = rows%as2dFloat() elseif(present(defaultVal)) then - nodeAs2dFloats = defaultVal + nodeAs2dFloat = defaultVal else call IO_error(143,ext_msg=k) endif -end function tNode_get_byKey_as2dFloats +end function tNode_get_byKey_as2dFloat !-------------------------------------------------------------------------------------------------- !> @brief Access by key and convert to int array !-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_asInts(self,k,defaultVal,requiredSize) result(nodeAsInts) +function tNode_get_byKey_as1dInt(self,k,defaultVal,requiredSize) result(nodeAs1dInt) class(tNode), intent(in), target :: self character(len=*), intent(in) :: k integer, dimension(:), intent(in), optional :: defaultVal integer, intent(in), optional :: requiredSize - integer, dimension(:), allocatable :: nodeAsInts + integer, dimension(:), allocatable :: nodeAs1dInt class(tNode), pointer :: node type(tList), pointer :: list @@ -898,29 +898,29 @@ function tNode_get_byKey_asInts(self,k,defaultVal,requiredSize) result(nodeAsInt if (self%contains(k)) then node => self%get(k) list => node%asList() - nodeAsInts = list%asInts() + nodeAs1dInt = list%as1dInt() elseif (present(defaultVal)) then - nodeAsInts = defaultVal + nodeAs1dInt = defaultVal else call IO_error(143,ext_msg=k) endif if (present(requiredSize)) then - if (requiredSize /= size(nodeAsInts)) call IO_error(146,ext_msg=k) + if (requiredSize /= size(nodeAs1dInt)) call IO_error(146,ext_msg=k) endif -end function tNode_get_byKey_asInts +end function tNode_get_byKey_as1dInt !-------------------------------------------------------------------------------------------------- !> @brief Access by key and convert to bool array !-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_asBools(self,k,defaultVal) result(nodeAsBools) +function tNode_get_byKey_as1dBool(self,k,defaultVal) result(nodeAs1dBool) class(tNode), intent(in), target :: self character(len=*), intent(in) :: k logical, dimension(:), intent(in), optional :: defaultVal - logical, dimension(:), allocatable :: nodeAsBools + logical, dimension(:), allocatable :: nodeAs1dBool class(tNode), pointer :: node type(tList), pointer :: list @@ -928,25 +928,25 @@ function tNode_get_byKey_asBools(self,k,defaultVal) result(nodeAsBools) if (self%contains(k)) then node => self%get(k) list => node%asList() - nodeAsBools = list%asBools() + nodeAs1dBool = list%as1dBool() elseif (present(defaultVal)) then - nodeAsBools = defaultVal + nodeAs1dBool = defaultVal else call IO_error(143,ext_msg=k) endif -end function tNode_get_byKey_asBools +end function tNode_get_byKey_as1dBool !-------------------------------------------------------------------------------------------------- !> @brief Access by key and convert to string array !-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_asStrings(self,k,defaultVal) result(nodeAsStrings) +function tNode_get_byKey_as1dString(self,k,defaultVal) result(nodeAs1dString) class(tNode), intent(in), target :: self character(len=*), intent(in) :: k character(len=*), intent(in), dimension(:), optional :: defaultVal - character(len=:), allocatable, dimension(:) :: nodeAsStrings + character(len=:), allocatable, dimension(:) :: nodeAs1dString class(tNode), pointer :: node type(tList), pointer :: list @@ -954,20 +954,20 @@ function tNode_get_byKey_asStrings(self,k,defaultVal) result(nodeAsStrings) if (self%contains(k)) then node => self%get(k) list => node%asList() - nodeAsStrings = list%asStrings() + nodeAs1dString = list%as1dString() elseif (present(defaultVal)) then - nodeAsStrings = defaultVal + nodeAs1dString = defaultVal else call IO_error(143,ext_msg=k) endif -end function tNode_get_byKey_asStrings +end function tNode_get_byKey_as1dString !-------------------------------------------------------------------------------------------------- !> @brief Returns string output array (hack for GNU) !-------------------------------------------------------------------------------------------------- -function output_asStrings(self) result(output) !ToDo: SR: Remove whenever GNU works +function output_as1dString(self) result(output) !ToDo: SR: Remove whenever GNU works class(tNode), pointer,intent(in) :: self character(len=pStringLen), allocatable, dimension(:) :: output @@ -982,7 +982,7 @@ function output_asStrings(self) result(output) !ToDo: SR: Rem enddo -end function output_asStrings +end function output_as1dString !-------------------------------------------------------------------------------------------------- @@ -1148,33 +1148,33 @@ end function tScalar_asString !-------------------------------------------------------------------------------------------------- !> @brief Convert to float array !-------------------------------------------------------------------------------------------------- -function tList_asFloats(self) +function tList_as1dFloat(self) class(tList), intent(in), target :: self - real(pReal), dimension(:), allocatable :: tList_asFloats + real(pReal), dimension(:), allocatable :: tList_as1dFloat integer :: i type(tItem), pointer :: item type(tScalar), pointer :: scalar - allocate(tList_asFloats(self%length)) + allocate(tList_as1dFloat(self%length)) item => self%first do i = 1, self%length scalar => item%node%asScalar() - tList_asFloats(i) = scalar%asFloat() + tList_as1dFloat(i) = scalar%asFloat() item => item%next enddo -end function tList_asFloats +end function tList_as1dFloat !-------------------------------------------------------------------------------------------------- !> @brief Convert to 2D float array !-------------------------------------------------------------------------------------------------- -function tList_as2dFloats(self) +function tList_as2dFloat(self) class(tList), intent(in), target :: self - real(pReal), dimension(:,:), allocatable :: tList_as2dFloats + real(pReal), dimension(:,:), allocatable :: tList_as2dFloat integer :: i class(tNode), pointer :: row @@ -1182,68 +1182,68 @@ function tList_as2dFloats(self) row => self%get(1) !SR: some interface called 'shape' may be used? row_data => row%asList() - allocate(tList_as2dFloats(row%length,row_data%length),source=0.0_pReal) + allocate(tList_as2dFloat(row%length,row_data%length),source=0.0_pReal) do i=1,self%length - tList_as2dFloats(i,:) = self%get_asFloats(i) + tList_as2dFloat(i,:) = self%get_as1dFloat(i) enddo -end function tList_as2dFloats +end function tList_as2dFloat !-------------------------------------------------------------------------------------------------- !> @brief Convert to int array !-------------------------------------------------------------------------------------------------- -function tList_asInts(self) +function tList_as1dInt(self) class(tList), intent(in), target :: self - integer, dimension(:), allocatable :: tList_asInts + integer, dimension(:), allocatable :: tList_as1dInt integer :: i type(tItem), pointer :: item type(tScalar), pointer :: scalar - allocate(tList_asInts(self%length)) + allocate(tList_as1dInt(self%length)) item => self%first do i = 1, self%length scalar => item%node%asScalar() - tList_asInts(i) = scalar%asInt() + tList_as1dInt(i) = scalar%asInt() item => item%next enddo -end function tList_asInts +end function tList_as1dInt !-------------------------------------------------------------------------------------------------- !> @brief Convert to bool array !-------------------------------------------------------------------------------------------------- -function tList_asBools(self) +function tList_as1dBool(self) class(tList), intent(in), target :: self - logical, dimension(:), allocatable :: tList_asBools + logical, dimension(:), allocatable :: tList_as1dBool integer :: i type(tItem), pointer :: item type(tScalar), pointer :: scalar - allocate(tList_asBools(self%length)) + allocate(tList_as1dBool(self%length)) item => self%first do i = 1, self%length scalar => item%node%asScalar() - tList_asBools(i) = scalar%asBool() + tList_as1dBool(i) = scalar%asBool() item => item%next enddo -end function tList_asBools +end function tList_as1dBool !-------------------------------------------------------------------------------------------------- !> @brief Convert to string array !-------------------------------------------------------------------------------------------------- -function tList_asStrings(self) +function tList_as1dString(self) class(tList), intent(in), target :: self - character(len=:), allocatable, dimension(:) :: tList_asStrings + character(len=:), allocatable, dimension(:) :: tList_as1dString integer :: i,len_max type(tItem), pointer :: item @@ -1257,15 +1257,15 @@ function tList_asStrings(self) item => item%next enddo - allocate(character(len=len_max) :: tList_asStrings(self%length)) + allocate(character(len=len_max) :: tList_as1dString(self%length)) item => self%first do i = 1, self%length scalar => item%node%asScalar() - tList_asStrings(i) = scalar%asString() + tList_as1dString(i) = scalar%asString() item => item%next enddo -end function tList_asStrings +end function tList_as1dString !-------------------------------------------------------------------------------------------------- diff --git a/src/grid/DAMASK_grid.f90 b/src/grid/DAMASK_grid.f90 index 0aa462e7e..c9c13e243 100644 --- a/src/grid/DAMASK_grid.f90 +++ b/src/grid/DAMASK_grid.f90 @@ -220,7 +220,7 @@ program DAMASK_grid loadCases(l)%stress%mask = transpose(reshape(temp_maskVector,[3,3])) loadCases(l)%stress%values = math_9to33(temp_valueVector) end select - call loadCases(l)%rot%fromAxisAngle(step_mech%get_asFloats('R',defaultVal = real([0.0,0.0,1.0,0.0],pReal)),degrees=.true.) + call loadCases(l)%rot%fromAxisAngle(step_mech%get_as1dFloat('R',defaultVal = real([0.0,0.0,1.0,0.0],pReal)),degrees=.true.) enddo readMech if (.not. allocated(loadCases(l)%deformation%myType)) call IO_error(error_ID=837,ext_msg = 'L/dot_F/F missing') diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index 993ea84f6..495cb0beb 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -48,9 +48,9 @@ module subroutine damage_init() if (configHomogenization%contains('damage')) then configHomogenizationDamage => configHomogenization%get('damage') #if defined (__GFORTRAN__) - prm%output = output_asStrings(configHomogenizationDamage) + prm%output = output_as1dString(configHomogenizationDamage) #else - prm%output = configHomogenizationDamage%get_asStrings('output',defaultVal=emptyStringArray) + prm%output = configHomogenizationDamage%get_as1dString('output',defaultVal=emptyStringArray) #endif else prm%output = emptyStringArray diff --git a/src/homogenization_mechanical_RGC.f90 b/src/homogenization_mechanical_RGC.f90 index a68e9b772..1ea940031 100644 --- a/src/homogenization_mechanical_RGC.f90 +++ b/src/homogenization_mechanical_RGC.f90 @@ -146,20 +146,20 @@ module subroutine mechanical_RGC_init(num_homogMech) dst => dependentState(ho)) #if defined (__GFORTRAN__) - prm%output = output_asStrings(homogMech) + prm%output = output_as1dString(homogMech) #else - prm%output = homogMech%get_asStrings('output',defaultVal=emptyStringArray) + prm%output = homogMech%get_as1dString('output',defaultVal=emptyStringArray) #endif - prm%N_constituents = homogMech%get_asInts('cluster_size',requiredSize=3) + prm%N_constituents = homogMech%get_as1dInt('cluster_size',requiredSize=3) if (homogenization_Nconstituents(ho) /= product(prm%N_constituents)) & call IO_error(211,ext_msg='N_constituents (mechanical_RGC)') prm%xi_alpha = homogMech%get_asFloat('xi_alpha') prm%c_alpha = homogMech%get_asFloat('c_alpha') - prm%D_alpha = homogMech%get_asFloats('D_alpha', requiredSize=3) - prm%a_g = homogMech%get_asFloats('a_g', requiredSize=3) + prm%D_alpha = homogMech%get_as1dFloat('D_alpha', requiredSize=3) + prm%a_g = homogMech%get_as1dFloat('a_g', requiredSize=3) Nmaterialpoints = count(material_homogenizationAt == ho) nIntFaceTot = 3*( (prm%N_constituents(1)-1)*prm%N_constituents(2)*prm%N_constituents(3) & diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index efb6e7b58..7602e50d2 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -51,9 +51,9 @@ module subroutine thermal_init() if (configHomogenization%contains('thermal')) then configHomogenizationThermal => configHomogenization%get('thermal') #if defined (__GFORTRAN__) - prm%output = output_asStrings(configHomogenizationThermal) + prm%output = output_as1dString(configHomogenizationThermal) #else - prm%output = configHomogenizationThermal%get_asStrings('output',defaultVal=emptyStringArray) + prm%output = configHomogenizationThermal%get_as1dString('output',defaultVal=emptyStringArray) #endif else prm%output = emptyStringArray diff --git a/src/phase_damage_anisobrittle.f90 b/src/phase_damage_anisobrittle.f90 index 096da6fb8..3c573f33a 100644 --- a/src/phase_damage_anisobrittle.f90 +++ b/src/phase_damage_anisobrittle.f90 @@ -64,14 +64,14 @@ module function anisobrittle_init() result(mySources) associate(prm => param(p)) src => sources%get(1) - N_cl = src%get_asInts('N_cl',defaultVal=emptyIntArray) + N_cl = src%get_as1dInt('N_cl',defaultVal=emptyIntArray) prm%sum_N_cl = sum(abs(N_cl)) prm%q = src%get_asFloat('q') prm%dot_o = src%get_asFloat('dot_o') - prm%s_crit = src%get_asFloats('s_crit', requiredSize=size(N_cl)) - prm%g_crit = src%get_asFloats('g_crit', requiredSize=size(N_cl)) + prm%s_crit = src%get_as1dFloat('s_crit', requiredSize=size(N_cl)) + prm%g_crit = src%get_as1dFloat('g_crit', requiredSize=size(N_cl)) prm%cleavage_systems = lattice_SchmidMatrix_cleavage(N_cl,phase%get_asString('lattice'),& phase%get_asFloat('c/a',defaultVal=0.0_pReal)) @@ -81,9 +81,9 @@ module function anisobrittle_init() result(mySources) prm%g_crit = math_expand(prm%g_crit,N_cl) #if defined (__GFORTRAN__) - prm%output = output_asStrings(src) + prm%output = output_as1dString(src) #else - prm%output = src%get_asStrings('output',defaultVal=emptyStringArray) + prm%output = src%get_as1dString('output',defaultVal=emptyStringArray) #endif ! sanity checks diff --git a/src/phase_damage_anisoductile.f90 b/src/phase_damage_anisoductile.f90 index a687df594..58991adf0 100644 --- a/src/phase_damage_anisoductile.f90 +++ b/src/phase_damage_anisoductile.f90 @@ -61,17 +61,17 @@ module function anisoductile_init() result(mySources) associate(prm => param(p)) src => sources%get(1) - N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) + N_sl = pl%get_as1dInt('N_sl',defaultVal=emptyIntArray) prm%q = src%get_asFloat('q') - prm%gamma_crit = src%get_asFloats('gamma_crit',requiredSize=size(N_sl)) + prm%gamma_crit = src%get_as1dFloat('gamma_crit',requiredSize=size(N_sl)) ! expand: family => system prm%gamma_crit = math_expand(prm%gamma_crit,N_sl) #if defined (__GFORTRAN__) - prm%output = output_asStrings(src) + prm%output = output_as1dString(src) #else - prm%output = src%get_asStrings('output',defaultVal=emptyStringArray) + prm%output = src%get_as1dString('output',defaultVal=emptyStringArray) #endif ! sanity checks diff --git a/src/phase_damage_isobrittle.f90 b/src/phase_damage_isobrittle.f90 index 0cf85897a..3c7866e66 100644 --- a/src/phase_damage_isobrittle.f90 +++ b/src/phase_damage_isobrittle.f90 @@ -56,9 +56,9 @@ module function isobrittle_init() result(mySources) prm%W_crit = src%get_asFloat('W_crit') #if defined (__GFORTRAN__) - prm%output = output_asStrings(src) + prm%output = output_as1dString(src) #else - prm%output = src%get_asStrings('output',defaultVal=emptyStringArray) + prm%output = src%get_as1dString('output',defaultVal=emptyStringArray) #endif ! sanity checks diff --git a/src/phase_damage_isoductile.f90 b/src/phase_damage_isoductile.f90 index 9d00bb1a7..b5ca9a1c2 100644 --- a/src/phase_damage_isoductile.f90 +++ b/src/phase_damage_isoductile.f90 @@ -59,9 +59,9 @@ module function isoductile_init() result(mySources) prm%gamma_crit = src%get_asFloat('gamma_crit') #if defined (__GFORTRAN__) - prm%output = output_asStrings(src) + prm%output = output_as1dString(src) #else - prm%output = src%get_asStrings('output',defaultVal=emptyStringArray) + prm%output = src%get_as1dString('output',defaultVal=emptyStringArray) #endif ! sanity checks diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index e642b22ef..08053aed8 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -249,9 +249,9 @@ module subroutine mechanical_init(materials,phases) phase => phases%get(ph) mech => phase%get('mechanics') #if defined(__GFORTRAN__) - output_constituent(ph)%label = output_asStrings(mech) + output_constituent(ph)%label = output_as1dString(mech) #else - output_constituent(ph)%label = mech%get_asStrings('output',defaultVal=emptyStringArray) + output_constituent(ph)%label = mech%get_as1dString('output',defaultVal=emptyStringArray) #endif elastic => mech%get('elasticity') if(elastic%get_asString('type') == 'hooke') then @@ -288,7 +288,7 @@ module subroutine mechanical_init(materials,phases) ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) - call material_orientation0(co,ph,me)%fromQuaternion(constituent%get_asFloats('O',requiredSize=4)) + call material_orientation0(co,ph,me)%fromQuaternion(constituent%get_as1dFloat('O',requiredSize=4)) phase_mechanical_Fp0(ph)%data(1:3,1:3,me) = material_orientation0(co,ph,me)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) phase_mechanical_Fp0(ph)%data(1:3,1:3,me) = phase_mechanical_Fp0(ph)%data(1:3,1:3,me) & diff --git a/src/phase_mechanical_eigen_slipplaneopening.f90 b/src/phase_mechanical_eigen_slipplaneopening.f90 index e8a7d65b9..23b18c40c 100644 --- a/src/phase_mechanical_eigen_slipplaneopening.f90 +++ b/src/phase_mechanical_eigen_slipplaneopening.f90 @@ -71,7 +71,7 @@ module function kinematics_slipplane_opening_init() result(myKinematics) prm%dot_o = kinematic_type%get_asFloat('dot_o') prm%q = kinematic_type%get_asFloat('q') - N_sl = pl%get_asInts('N_sl') + N_sl = pl%get_as1dInt('N_sl') prm%sum_N_sl = sum(abs(N_sl)) d = lattice_slip_direction (N_sl,phase%get_asString('lattice'),& @@ -88,7 +88,7 @@ module function kinematics_slipplane_opening_init() result(myKinematics) prm%P_n(1:3,1:3,i) = math_outer(n(1:3,i), n(1:3,i)) enddo - prm%g_crit = kinematic_type%get_asFloats('g_crit',requiredSize=size(N_sl)) + prm%g_crit = kinematic_type%get_as1dFloat('g_crit',requiredSize=size(N_sl)) ! expand: family => system prm%g_crit = math_expand(prm%g_crit,N_sl) diff --git a/src/phase_mechanical_eigen_thermalexpansion.f90 b/src/phase_mechanical_eigen_thermalexpansion.f90 index 86e7fa907..e47db4f37 100644 --- a/src/phase_mechanical_eigen_thermalexpansion.f90 +++ b/src/phase_mechanical_eigen_thermalexpansion.f90 @@ -60,11 +60,11 @@ module function thermalexpansion_init(kinematics_length) result(myKinematics) prm%T_ref = kinematic_type%get_asFloat('T_ref', defaultVal=0.0_pReal) ! read up to three parameters (constant, linear, quadratic with T) - temp = kinematic_type%get_asFloats('A_11') + temp = kinematic_type%get_as1dFloat('A_11') prm%A(1,1,1:size(temp)) = temp - temp = kinematic_type%get_asFloats('A_22',defaultVal=[(0.0_pReal, i=1,size(temp))],requiredSize=size(temp)) + temp = kinematic_type%get_as1dFloat('A_22',defaultVal=[(0.0_pReal, i=1,size(temp))],requiredSize=size(temp)) prm%A(2,2,1:size(temp)) = temp - temp = kinematic_type%get_asFloats('A_33',defaultVal=[(0.0_pReal, i=1,size(temp))],requiredSize=size(temp)) + temp = kinematic_type%get_as1dFloat('A_33',defaultVal=[(0.0_pReal, i=1,size(temp))],requiredSize=size(temp)) prm%A(3,3,1:size(temp)) = temp do i=1, size(prm%A,3) prm%A(1:3,1:3,i) = lattice_applyLatticeSymmetry33(prm%A(1:3,1:3,i),& diff --git a/src/phase_mechanical_plastic_dislotungsten.f90 b/src/phase_mechanical_plastic_dislotungsten.f90 index 1fda51a58..3510d3498 100644 --- a/src/phase_mechanical_plastic_dislotungsten.f90 +++ b/src/phase_mechanical_plastic_dislotungsten.f90 @@ -124,9 +124,9 @@ module function plastic_dislotungsten_init() result(myPlasticity) pl => mech%get('plasticity') #if defined (__GFORTRAN__) - prm%output = output_asStrings(pl) + prm%output = output_as1dString(pl) #else - prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray) + prm%output = pl%get_as1dString('output',defaultVal=emptyStringArray) #endif ! This data is read in already in lattice @@ -134,14 +134,14 @@ module function plastic_dislotungsten_init() result(myPlasticity) !-------------------------------------------------------------------------------------------------- ! slip related parameters - N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) + N_sl = pl%get_as1dInt('N_sl',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(N_sl)) slipActive: if (prm%sum_N_sl > 0) then prm%P_sl = lattice_SchmidMatrix_slip(N_sl,phase%get_asString('lattice'),& phase%get_asFloat('c/a',defaultVal=0.0_pReal)) if(trim(phase%get_asString('lattice')) == 'cI') then - a = pl%get_asFloats('a_nonSchmid',defaultVal = emptyRealArray) + a = pl%get_as1dFloat('a_nonSchmid',defaultVal = emptyRealArray) prm%nonSchmid_pos = lattice_nonSchmidMatrix(N_sl,a,+1) prm%nonSchmid_neg = lattice_nonSchmidMatrix(N_sl,a,-1) else @@ -149,28 +149,28 @@ module function plastic_dislotungsten_init() result(myPlasticity) prm%nonSchmid_neg = prm%P_sl endif - prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,pl%get_asFloats('h_sl_sl'), & + prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,pl%get_as1dFloat('h_sl_sl'), & phase%get_asString('lattice')) prm%forestProjection = lattice_forestProjection_edge(N_sl,phase%get_asString('lattice'),& phase%get_asFloat('c/a',defaultVal=0.0_pReal)) prm%forestProjection = transpose(prm%forestProjection) - rho_mob_0 = pl%get_asFloats('rho_mob_0', requiredSize=size(N_sl)) - rho_dip_0 = pl%get_asFloats('rho_dip_0', requiredSize=size(N_sl)) - prm%v_0 = pl%get_asFloats('v_0', requiredSize=size(N_sl)) - prm%b_sl = pl%get_asFloats('b_sl', requiredSize=size(N_sl)) - prm%Q_s = pl%get_asFloats('Q_s', requiredSize=size(N_sl)) + rho_mob_0 = pl%get_as1dFloat('rho_mob_0', requiredSize=size(N_sl)) + rho_dip_0 = pl%get_as1dFloat('rho_dip_0', requiredSize=size(N_sl)) + prm%v_0 = pl%get_as1dFloat('v_0', requiredSize=size(N_sl)) + prm%b_sl = pl%get_as1dFloat('b_sl', requiredSize=size(N_sl)) + prm%Q_s = pl%get_as1dFloat('Q_s', requiredSize=size(N_sl)) - prm%i_sl = pl%get_asFloats('i_sl', requiredSize=size(N_sl)) - prm%tau_Peierls = pl%get_asFloats('tau_Peierls', requiredSize=size(N_sl)) - prm%p = pl%get_asFloats('p_sl', requiredSize=size(N_sl), & + prm%i_sl = pl%get_as1dFloat('i_sl', requiredSize=size(N_sl)) + prm%tau_Peierls = pl%get_as1dFloat('tau_Peierls', requiredSize=size(N_sl)) + prm%p = pl%get_as1dFloat('p_sl', requiredSize=size(N_sl), & defaultVal=[(1.0_pReal,i=1,size(N_sl))]) - prm%q = pl%get_asFloats('q_sl', requiredSize=size(N_sl), & + prm%q = pl%get_as1dFloat('q_sl', requiredSize=size(N_sl), & defaultVal=[(1.0_pReal,i=1,size(N_sl))]) - prm%h = pl%get_asFloats('h', requiredSize=size(N_sl)) - prm%w = pl%get_asFloats('w', requiredSize=size(N_sl)) - prm%omega = pl%get_asFloats('omega', requiredSize=size(N_sl)) - prm%B = pl%get_asFloats('B', requiredSize=size(N_sl)) + prm%h = pl%get_as1dFloat('h', requiredSize=size(N_sl)) + prm%w = pl%get_as1dFloat('w', requiredSize=size(N_sl)) + prm%omega = pl%get_as1dFloat('omega', requiredSize=size(N_sl)) + prm%B = pl%get_as1dFloat('B', requiredSize=size(N_sl)) prm%D = pl%get_asFloat('D') prm%D_0 = pl%get_asFloat('D_0') diff --git a/src/phase_mechanical_plastic_dislotwin.f90 b/src/phase_mechanical_plastic_dislotwin.f90 index 5500ae731..7d6e3bdf6 100644 --- a/src/phase_mechanical_plastic_dislotwin.f90 +++ b/src/phase_mechanical_plastic_dislotwin.f90 @@ -177,9 +177,9 @@ module function plastic_dislotwin_init() result(myPlasticity) pl => mech%get('plasticity') #if defined (__GFORTRAN__) - prm%output = output_asStrings(pl) + prm%output = output_as1dString(pl) #else - prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray) + prm%output = pl%get_as1dString('output',defaultVal=emptyStringArray) #endif ! This data is read in already in lattice @@ -189,12 +189,12 @@ module function plastic_dislotwin_init() result(myPlasticity) !-------------------------------------------------------------------------------------------------- ! slip related parameters - N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) + N_sl = pl%get_as1dInt('N_sl',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(N_sl)) slipActive: if (prm%sum_N_sl > 0) then prm%P_sl = lattice_SchmidMatrix_slip(N_sl,phase%get_asString('lattice'),& phase%get_asFloat('c/a',defaultVal=0.0_pReal)) - prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,pl%get_asFloats('h_sl_sl'), & + prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,pl%get_as1dFloat('h_sl_sl'), & phase%get_asString('lattice')) prm%forestProjection = lattice_forestProjection_edge(N_sl,phase%get_asString('lattice'),& phase%get_asFloat('c/a',defaultVal=0.0_pReal)) @@ -205,16 +205,16 @@ module function plastic_dislotwin_init() result(myPlasticity) prm%fccTwinTransNucleation = lattice_structure(ph) == lattice_FCC_ID .and. (N_sl(1) == 12) if(prm%fccTwinTransNucleation) prm%fcc_twinNucleationSlipPair = lattice_FCC_TWINNUCLEATIONSLIPPAIR - rho_mob_0 = pl%get_asFloats('rho_mob_0', requiredSize=size(N_sl)) - rho_dip_0 = pl%get_asFloats('rho_dip_0', requiredSize=size(N_sl)) - prm%v_0 = pl%get_asFloats('v_0', requiredSize=size(N_sl)) - prm%b_sl = pl%get_asFloats('b_sl', requiredSize=size(N_sl)) - prm%Q_s = pl%get_asFloats('Q_s', requiredSize=size(N_sl)) - prm%i_sl = pl%get_asFloats('i_sl', requiredSize=size(N_sl)) - prm%p = pl%get_asFloats('p_sl', requiredSize=size(N_sl)) - prm%q = pl%get_asFloats('q_sl', requiredSize=size(N_sl)) - prm%tau_0 = pl%get_asFloats('tau_0', requiredSize=size(N_sl)) - prm%B = pl%get_asFloats('B', requiredSize=size(N_sl), & + rho_mob_0 = pl%get_as1dFloat('rho_mob_0', requiredSize=size(N_sl)) + rho_dip_0 = pl%get_as1dFloat('rho_dip_0', requiredSize=size(N_sl)) + prm%v_0 = pl%get_as1dFloat('v_0', requiredSize=size(N_sl)) + prm%b_sl = pl%get_as1dFloat('b_sl', requiredSize=size(N_sl)) + prm%Q_s = pl%get_as1dFloat('Q_s', requiredSize=size(N_sl)) + prm%i_sl = pl%get_as1dFloat('i_sl', requiredSize=size(N_sl)) + prm%p = pl%get_as1dFloat('p_sl', requiredSize=size(N_sl)) + prm%q = pl%get_as1dFloat('q_sl', requiredSize=size(N_sl)) + prm%tau_0 = pl%get_as1dFloat('tau_0', requiredSize=size(N_sl)) + prm%B = pl%get_as1dFloat('B', requiredSize=size(N_sl), & defaultVal=[(0.0_pReal, i=1,size(N_sl))]) prm%D_a = pl%get_asFloat('D_a') @@ -265,18 +265,18 @@ module function plastic_dislotwin_init() result(myPlasticity) !-------------------------------------------------------------------------------------------------- ! twin related parameters - N_tw = pl%get_asInts('N_tw', defaultVal=emptyIntArray) + N_tw = pl%get_as1dInt('N_tw', defaultVal=emptyIntArray) prm%sum_N_tw = sum(abs(N_tw)) twinActive: if (prm%sum_N_tw > 0) then prm%P_tw = lattice_SchmidMatrix_twin(N_tw,phase%get_asString('lattice'),& phase%get_asFloat('c/a',defaultVal=0.0_pReal)) prm%h_tw_tw = lattice_interaction_TwinByTwin(N_tw,& - pl%get_asFloats('h_tw_tw'), & + pl%get_as1dFloat('h_tw_tw'), & phase%get_asString('lattice')) - prm%b_tw = pl%get_asFloats('b_tw', requiredSize=size(N_tw)) - prm%t_tw = pl%get_asFloats('t_tw', requiredSize=size(N_tw)) - prm%r = pl%get_asFloats('p_tw', requiredSize=size(N_tw)) + prm%b_tw = pl%get_as1dFloat('b_tw', requiredSize=size(N_tw)) + prm%t_tw = pl%get_as1dFloat('t_tw', requiredSize=size(N_tw)) + prm%r = pl%get_as1dFloat('p_tw', requiredSize=size(N_tw)) prm%x_c_tw = pl%get_asFloat('x_c_tw') prm%L_tw = pl%get_asFloat('L_tw') @@ -289,7 +289,7 @@ module function plastic_dislotwin_init() result(myPlasticity) phase%get_asFloat('c/a',defaultVal=0.0_pReal)) if (.not. prm%fccTwinTransNucleation) then - prm%dot_N_0_tw = pl%get_asFloats('dot_N_0_tw') + prm%dot_N_0_tw = pl%get_as1dFloat('dot_N_0_tw') prm%dot_N_0_tw = math_expand(prm%dot_N_0_tw,N_tw) endif @@ -315,10 +315,10 @@ module function plastic_dislotwin_init() result(myPlasticity) !-------------------------------------------------------------------------------------------------- ! transformation related parameters - N_tr = pl%get_asInts('N_tr', defaultVal=emptyIntArray) + N_tr = pl%get_as1dInt('N_tr', defaultVal=emptyIntArray) prm%sum_N_tr = sum(abs(N_tr)) transActive: if (prm%sum_N_tr > 0) then - prm%b_tr = pl%get_asFloats('b_tr') + prm%b_tr = pl%get_as1dFloat('b_tr') prm%b_tr = math_expand(prm%b_tr,N_tr) prm%h = pl%get_asFloat('h', defaultVal=0.0_pReal) ! ToDo: How to handle that??? @@ -327,7 +327,7 @@ module function plastic_dislotwin_init() result(myPlasticity) prm%x_c_tr = pl%get_asFloat('x_c_tr', defaultVal=0.0_pReal) ! ToDo: How to handle that??? prm%L_tr = pl%get_asFloat('L_tr') - prm%h_tr_tr = lattice_interaction_TransByTrans(N_tr,pl%get_asFloats('h_tr_tr'), & + prm%h_tr_tr = lattice_interaction_TransByTrans(N_tr,pl%get_as1dFloat('h_tr_tr'), & phase%get_asString('lattice')) prm%C66_tr = lattice_C66_trans(N_tr,prm%C66,pl%get_asString('lattice_tr'), & @@ -341,12 +341,12 @@ module function plastic_dislotwin_init() result(myPlasticity) pl%get_asFloat('a_cF', defaultVal=0.0_pReal)) if (lattice_structure(ph) /= lattice_FCC_ID) then - prm%dot_N_0_tr = pl%get_asFloats('dot_N_0_tr') + prm%dot_N_0_tr = pl%get_as1dFloat('dot_N_0_tr') prm%dot_N_0_tr = math_expand(prm%dot_N_0_tr,N_tr) endif - prm%t_tr = pl%get_asFloats('t_tr') + prm%t_tr = pl%get_as1dFloat('t_tr') prm%t_tr = math_expand(prm%t_tr,N_tr) - prm%s = pl%get_asFloats('p_tr',defaultVal=[0.0_pReal]) + prm%s = pl%get_as1dFloat('p_tr',defaultVal=[0.0_pReal]) prm%s = math_expand(prm%s,N_tr) ! sanity checks @@ -392,14 +392,14 @@ module function plastic_dislotwin_init() result(myPlasticity) slipAndTwinActive: if (prm%sum_N_sl * prm%sum_N_tw > 0) then prm%h_sl_tw = lattice_interaction_SlipByTwin(N_sl,N_tw,& - pl%get_asFloats('h_sl_tw'), & + pl%get_as1dFloat('h_sl_tw'), & phase%get_asString('lattice')) if (prm%fccTwinTransNucleation .and. size(N_tw) /= 1) extmsg = trim(extmsg)//' interaction_sliptwin' endif slipAndTwinActive slipAndTransActive: if (prm%sum_N_sl * prm%sum_N_tr > 0) then prm%h_sl_tr = lattice_interaction_SlipByTrans(N_sl,N_tr,& - pl%get_asFloats('h_sl_tr'), & + pl%get_as1dFloat('h_sl_tr'), & phase%get_asString('lattice')) if (prm%fccTwinTransNucleation .and. size(N_tr) /= 1) extmsg = trim(extmsg)//' interaction_sliptrans' endif slipAndTransActive diff --git a/src/phase_mechanical_plastic_isotropic.f90 b/src/phase_mechanical_plastic_isotropic.f90 index d02436fba..561a22a1d 100644 --- a/src/phase_mechanical_plastic_isotropic.f90 +++ b/src/phase_mechanical_plastic_isotropic.f90 @@ -89,9 +89,9 @@ module function plastic_isotropic_init() result(myPlasticity) pl => mech%get('plasticity') #if defined (__GFORTRAN__) - prm%output = output_asStrings(pl) + prm%output = output_as1dString(pl) #else - prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray) + prm%output = pl%get_as1dString('output',defaultVal=emptyStringArray) #endif xi_0 = pl%get_asFloat('xi_0') diff --git a/src/phase_mechanical_plastic_kinehardening.f90 b/src/phase_mechanical_plastic_kinehardening.f90 index 75e8d9e59..e0c20bff4 100644 --- a/src/phase_mechanical_plastic_kinehardening.f90 +++ b/src/phase_mechanical_plastic_kinehardening.f90 @@ -102,21 +102,21 @@ module function plastic_kinehardening_init() result(myPlasticity) pl => mech%get('plasticity') #if defined (__GFORTRAN__) - prm%output = output_asStrings(pl) + prm%output = output_as1dString(pl) #else - prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray) + prm%output = pl%get_as1dString('output',defaultVal=emptyStringArray) #endif !-------------------------------------------------------------------------------------------------- ! slip related parameters - N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) + N_sl = pl%get_as1dInt('N_sl',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(N_sl)) slipActive: if (prm%sum_N_sl > 0) then prm%P = lattice_SchmidMatrix_slip(N_sl,phase%get_asString('lattice'),& phase%get_asFloat('c/a',defaultVal=0.0_pReal)) if(trim(phase%get_asString('lattice')) == 'cI') then - a = pl%get_asFloats('a_nonSchmid',defaultVal = emptyRealArray) + a = pl%get_as1dFloat('a_nonSchmid',defaultVal = emptyRealArray) if(size(a) > 0) prm%nonSchmidActive = .true. prm%nonSchmid_pos = lattice_nonSchmidMatrix(N_sl,a,+1) prm%nonSchmid_neg = lattice_nonSchmidMatrix(N_sl,a,-1) @@ -125,16 +125,16 @@ module function plastic_kinehardening_init() result(myPlasticity) prm%nonSchmid_neg = prm%P endif prm%interaction_SlipSlip = lattice_interaction_SlipBySlip(N_sl, & - pl%get_asFloats('h_sl_sl'), & + pl%get_as1dFloat('h_sl_sl'), & phase%get_asString('lattice')) - xi_0 = pl%get_asFloats('xi_0', requiredSize=size(N_sl)) - prm%xi_inf_f = pl%get_asFloats('xi_inf_f', requiredSize=size(N_sl)) - prm%xi_inf_b = pl%get_asFloats('xi_inf_b', requiredSize=size(N_sl)) - prm%h_0_f = pl%get_asFloats('h_0_f', requiredSize=size(N_sl)) - prm%h_inf_f = pl%get_asFloats('h_inf_f', requiredSize=size(N_sl)) - prm%h_0_b = pl%get_asFloats('h_0_b', requiredSize=size(N_sl)) - prm%h_inf_b = pl%get_asFloats('h_inf_b', requiredSize=size(N_sl)) + xi_0 = pl%get_as1dFloat('xi_0', requiredSize=size(N_sl)) + prm%xi_inf_f = pl%get_as1dFloat('xi_inf_f', requiredSize=size(N_sl)) + prm%xi_inf_b = pl%get_as1dFloat('xi_inf_b', requiredSize=size(N_sl)) + prm%h_0_f = pl%get_as1dFloat('h_0_f', requiredSize=size(N_sl)) + prm%h_inf_f = pl%get_as1dFloat('h_inf_f', requiredSize=size(N_sl)) + prm%h_0_b = pl%get_as1dFloat('h_0_b', requiredSize=size(N_sl)) + prm%h_inf_b = pl%get_as1dFloat('h_inf_b', requiredSize=size(N_sl)) prm%dot_gamma_0 = pl%get_asFloat('dot_gamma_0') prm%n = pl%get_asFloat('n') diff --git a/src/phase_mechanical_plastic_nonlocal.f90 b/src/phase_mechanical_plastic_nonlocal.f90 index d0007075b..09c4017ba 100644 --- a/src/phase_mechanical_plastic_nonlocal.f90 +++ b/src/phase_mechanical_plastic_nonlocal.f90 @@ -233,9 +233,9 @@ module function plastic_nonlocal_init() result(myPlasticity) phase_localPlasticity(ph) = .not. pl%contains('nonlocal') #if defined (__GFORTRAN__) - prm%output = output_asStrings(pl) + prm%output = output_as1dString(pl) #else - prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray) + prm%output = pl%get_as1dString('output',defaultVal=emptyStringArray) #endif prm%atol_rho = pl%get_asFloat('atol_rho',defaultVal=1.0e4_pReal) @@ -244,14 +244,14 @@ module function plastic_nonlocal_init() result(myPlasticity) prm%mu = lattice_mu(ph) prm%nu = lattice_nu(ph) - ini%N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) + ini%N_sl = pl%get_as1dInt('N_sl',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(ini%N_sl)) slipActive: if (prm%sum_N_sl > 0) then prm%Schmid = lattice_SchmidMatrix_slip(ini%N_sl,phase%get_asString('lattice'),& phase%get_asFloat('c/a',defaultVal=0.0_pReal)) if(trim(phase%get_asString('lattice')) == 'cI') then - a = pl%get_asFloats('a_nonSchmid',defaultVal = emptyRealArray) + a = pl%get_as1dFloat('a_nonSchmid',defaultVal = emptyRealArray) if(size(a) > 0) prm%nonSchmidActive = .true. prm%nonSchmid_pos = lattice_nonSchmidMatrix(ini%N_sl,a,+1) prm%nonSchmid_neg = lattice_nonSchmidMatrix(ini%N_sl,a,-1) @@ -261,7 +261,7 @@ module function plastic_nonlocal_init() result(myPlasticity) endif prm%h_sl_sl = lattice_interaction_SlipBySlip(ini%N_sl, & - pl%get_asFloats('h_sl_sl'), & + pl%get_as1dFloat('h_sl_sl'), & phase%get_asString('lattice')) prm%forestProjection_edge = lattice_forestProjection_edge (ini%N_sl,phase%get_asString('lattice'),& @@ -286,29 +286,29 @@ module function plastic_nonlocal_init() result(myPlasticity) enddo enddo - ini%rho_u_ed_pos_0 = pl%get_asFloats('rho_u_ed_pos_0', requiredSize=size(ini%N_sl)) - ini%rho_u_ed_neg_0 = pl%get_asFloats('rho_u_ed_neg_0', requiredSize=size(ini%N_sl)) - ini%rho_u_sc_pos_0 = pl%get_asFloats('rho_u_sc_pos_0', requiredSize=size(ini%N_sl)) - ini%rho_u_sc_neg_0 = pl%get_asFloats('rho_u_sc_neg_0', requiredSize=size(ini%N_sl)) - ini%rho_d_ed_0 = pl%get_asFloats('rho_d_ed_0', requiredSize=size(ini%N_sl)) - ini%rho_d_sc_0 = pl%get_asFloats('rho_d_sc_0', requiredSize=size(ini%N_sl)) + ini%rho_u_ed_pos_0 = pl%get_as1dFloat('rho_u_ed_pos_0', requiredSize=size(ini%N_sl)) + ini%rho_u_ed_neg_0 = pl%get_as1dFloat('rho_u_ed_neg_0', requiredSize=size(ini%N_sl)) + ini%rho_u_sc_pos_0 = pl%get_as1dFloat('rho_u_sc_pos_0', requiredSize=size(ini%N_sl)) + ini%rho_u_sc_neg_0 = pl%get_as1dFloat('rho_u_sc_neg_0', requiredSize=size(ini%N_sl)) + ini%rho_d_ed_0 = pl%get_as1dFloat('rho_d_ed_0', requiredSize=size(ini%N_sl)) + ini%rho_d_sc_0 = pl%get_as1dFloat('rho_d_sc_0', requiredSize=size(ini%N_sl)) - prm%i_sl = pl%get_asFloats('i_sl', requiredSize=size(ini%N_sl)) - prm%b_sl = pl%get_asFloats('b_sl', requiredSize=size(ini%N_sl)) + prm%i_sl = pl%get_as1dFloat('i_sl', requiredSize=size(ini%N_sl)) + prm%b_sl = pl%get_as1dFloat('b_sl', requiredSize=size(ini%N_sl)) prm%i_sl = math_expand(prm%i_sl,ini%N_sl) prm%b_sl = math_expand(prm%b_sl,ini%N_sl) - prm%d_ed = pl%get_asFloats('d_ed', requiredSize=size(ini%N_sl)) - prm%d_sc = pl%get_asFloats('d_sc', requiredSize=size(ini%N_sl)) + prm%d_ed = pl%get_as1dFloat('d_ed', requiredSize=size(ini%N_sl)) + prm%d_sc = pl%get_as1dFloat('d_sc', requiredSize=size(ini%N_sl)) prm%d_ed = math_expand(prm%d_ed,ini%N_sl) prm%d_sc = math_expand(prm%d_sc,ini%N_sl) allocate(prm%minDipoleHeight(prm%sum_N_sl,2)) prm%minDipoleHeight(:,1) = prm%d_ed prm%minDipoleHeight(:,2) = prm%d_sc - prm%tau_Peierls_ed = pl%get_asFloats('tau_Peierls_ed', requiredSize=size(ini%N_sl)) - prm%tau_Peierls_sc = pl%get_asFloats('tau_Peierls_sc', requiredSize=size(ini%N_sl)) + prm%tau_Peierls_ed = pl%get_as1dFloat('tau_Peierls_ed', requiredSize=size(ini%N_sl)) + prm%tau_Peierls_sc = pl%get_as1dFloat('tau_Peierls_sc', requiredSize=size(ini%N_sl)) prm%tau_Peierls_ed = math_expand(prm%tau_Peierls_ed,ini%N_sl) prm%tau_Peierls_sc = math_expand(prm%tau_Peierls_sc,ini%N_sl) allocate(prm%peierlsstress(prm%sum_N_sl,2)) diff --git a/src/phase_mechanical_plastic_phenopowerlaw.f90 b/src/phase_mechanical_plastic_phenopowerlaw.f90 index ae5926c0f..f15eeef48 100644 --- a/src/phase_mechanical_plastic_phenopowerlaw.f90 +++ b/src/phase_mechanical_plastic_phenopowerlaw.f90 @@ -112,14 +112,14 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) !-------------------------------------------------------------------------------------------------- ! slip related parameters - N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) + N_sl = pl%get_as1dInt('N_sl',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(N_sl)) slipActive: if (prm%sum_N_sl > 0) then prm%P_sl = lattice_SchmidMatrix_slip(N_sl,phase%get_asString('lattice'),& phase%get_asFloat('c/a',defaultVal=0.0_pReal)) if(phase%get_asString('lattice') == 'cI') then - a = pl%get_asFloats('a_nonSchmid',defaultVal=emptyRealArray) + a = pl%get_as1dFloat('a_nonSchmid',defaultVal=emptyRealArray) if(size(a) > 0) prm%nonSchmidActive = .true. prm%nonSchmid_pos = lattice_nonSchmidMatrix(N_sl,a,+1) prm%nonSchmid_neg = lattice_nonSchmidMatrix(N_sl,a,-1) @@ -128,12 +128,12 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) prm%nonSchmid_neg = prm%P_sl endif prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl, & - pl%get_asFloats('h_sl_sl'), & + pl%get_as1dFloat('h_sl_sl'), & phase%get_asString('lattice')) - xi_0_sl = pl%get_asFloats('xi_0_sl', requiredSize=size(N_sl)) - prm%xi_inf_sl = pl%get_asFloats('xi_inf_sl', requiredSize=size(N_sl)) - prm%h_int = pl%get_asFloats('h_int', requiredSize=size(N_sl), & + xi_0_sl = pl%get_as1dFloat('xi_0_sl', requiredSize=size(N_sl)) + prm%xi_inf_sl = pl%get_as1dFloat('xi_inf_sl', requiredSize=size(N_sl)) + prm%h_int = pl%get_as1dFloat('h_int', requiredSize=size(N_sl), & defaultVal=[(0.0_pReal,i=1,size(N_sl))]) prm%dot_gamma_0_sl = pl%get_asFloat('dot_gamma_0_sl') @@ -161,18 +161,18 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) !-------------------------------------------------------------------------------------------------- ! twin related parameters - N_tw = pl%get_asInts('N_tw', defaultVal=emptyIntArray) + N_tw = pl%get_as1dInt('N_tw', defaultVal=emptyIntArray) prm%sum_N_tw = sum(abs(N_tw)) twinActive: if (prm%sum_N_tw > 0) then prm%P_tw = lattice_SchmidMatrix_twin(N_tw,phase%get_asString('lattice'),& phase%get_asFloat('c/a',defaultVal=0.0_pReal)) prm%h_tw_tw = lattice_interaction_TwinByTwin(N_tw,& - pl%get_asFloats('h_tw_tw'), & + pl%get_as1dFloat('h_tw_tw'), & phase%get_asString('lattice')) prm%gamma_tw_char = lattice_characteristicShear_twin(N_tw,phase%get_asString('lattice'),& phase%get_asFloat('c/a',defaultVal=0.0_pReal)) - xi_0_tw = pl%get_asFloats('xi_0_tw',requiredSize=size(N_tw)) + xi_0_tw = pl%get_as1dFloat('xi_0_tw',requiredSize=size(N_tw)) prm%c_1 = pl%get_asFloat('c_1',defaultVal=0.0_pReal) prm%c_2 = pl%get_asFloat('c_2',defaultVal=1.0_pReal) @@ -201,10 +201,10 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) slipAndTwinActive: if (prm%sum_N_sl > 0 .and. prm%sum_N_tw > 0) then prm%h_0_tw_sl = pl%get_asFloat('h_0_tw_sl') prm%h_sl_tw = lattice_interaction_SlipByTwin(N_sl,N_tw,& - pl%get_asFloats('h_sl_tw'), & + pl%get_as1dFloat('h_sl_tw'), & phase%get_asString('lattice')) prm%h_tw_sl = lattice_interaction_TwinBySlip(N_tw,N_sl,& - pl%get_asFloats('h_tw_sl'), & + pl%get_as1dFloat('h_tw_sl'), & phase%get_asString('lattice')) else slipAndTwinActive allocate(prm%h_sl_tw(prm%sum_N_sl,prm%sum_N_tw)) ! at least one dimension is 0 @@ -216,9 +216,9 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) ! output pararameters #if defined (__GFORTRAN__) - prm%output = output_asStrings(pl) + prm%output = output_as1dString(pl) #else - prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray) + prm%output = pl%get_as1dString('output',defaultVal=emptyStringArray) #endif !-------------------------------------------------------------------------------------------------- diff --git a/src/phase_thermal_externalheat.f90 b/src/phase_thermal_externalheat.f90 index 257b4e282..8266ba7cf 100644 --- a/src/phase_thermal_externalheat.f90 +++ b/src/phase_thermal_externalheat.f90 @@ -62,10 +62,10 @@ module function externalheat_init(source_length) result(mySources) associate(prm => param(ph)) src => sources%get(so) - prm%t_n = src%get_asFloats('t_n') + prm%t_n = src%get_as1dFloat('t_n') prm%nIntervals = size(prm%t_n) - 1 - prm%f_T = src%get_asFloats('f_T',requiredSize = size(prm%t_n)) + prm%f_T = src%get_as1dFloat('f_T',requiredSize = size(prm%t_n)) Nmembers = count(material_phaseAt2 == ph) call phase_allocateState(thermalState(ph)%p(so),Nmembers,1,1,0) From a59af55f1a188bd159e04b78d05ebde11c3719cb Mon Sep 17 00:00:00 2001 From: Vitesh Shah Date: Wed, 10 Mar 2021 17:34:27 +0100 Subject: [PATCH 009/219] read data by one process and broadcast it --- src/grid/grid_mech_FEM.f90 | 20 ++++++++++++---- src/grid/grid_mech_spectral_basic.f90 | 24 +++++++++++++++----- src/grid/grid_mech_spectral_polarisation.f90 | 20 ++++++++++++---- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index 4bf2c6658..2980eb65d 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -235,10 +235,18 @@ subroutine grid_mechanical_FEM_init fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','r') groupHandle = HDF5_openGroup(fileHandle,'solver') - call HDF5_read(groupHandle,P_aim, 'P_aim') - call HDF5_read(groupHandle,F_aim, 'F_aim') - call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc') - call HDF5_read(groupHandle,F_aimDot, 'F_aimDot') + call HDF5_read(groupHandle,P_aim, 'P_aim',.false.) + call MPI_Bcast(P_aim,9,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' + call HDF5_read(groupHandle,F_aim, 'F_aim',.false.) + call MPI_Bcast(F_aim,9,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' + call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc',.false.) + call MPI_Bcast(F_aim_lastInc,9,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' + call HDF5_read(groupHandle,F_aimDot, 'F_aimDot',.false.) + call MPI_Bcast(F_aimDot,9,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' call HDF5_read(groupHandle,F, 'F') call HDF5_read(groupHandle,F_lastInc, 'F_lastInc') call HDF5_read(groupHandle,u_current, 'u') @@ -262,7 +270,11 @@ subroutine grid_mechanical_FEM_init restartRead2: if (interface_restartInc > 0) then print'(a,i0,a)', ' reading more restart data of increment ', interface_restartInc, ' from file' call HDF5_read(groupHandle,C_volAvg, 'C_volAvg') + call MPI_Bcast(C_volAvg,81,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc') + call MPI_Bcast(C_volAvgLastInc,81,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index 8249a2503..b2d84a66f 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -183,10 +183,18 @@ subroutine grid_mechanical_spectral_basic_init fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','r') groupHandle = HDF5_openGroup(fileHandle,'solver') - call HDF5_read(groupHandle,P_aim, 'P_aim') - call HDF5_read(groupHandle,F_aim, 'F_aim') - call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc') - call HDF5_read(groupHandle,F_aimDot, 'F_aimDot') + call HDF5_read(groupHandle,P_aim, 'P_aim',.false.) + call MPI_Bcast(P_aim,9,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' + call HDF5_read(groupHandle,F_aim, 'F_aim',.false.) + call MPI_Bcast(F_aim,9,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' + call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc',.false.) + call MPI_Bcast(F_aim_lastInc,9,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' + call HDF5_read(groupHandle,F_aimDot, 'F_aimDot',.false.) + call MPI_Bcast(F_aimDot,9,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' call HDF5_read(groupHandle,F, 'F') call HDF5_read(groupHandle,F_lastInc, 'F_lastInc') @@ -204,8 +212,12 @@ subroutine grid_mechanical_spectral_basic_init restartRead2: if (interface_restartInc > 0) then print'(a,i0,a)', ' reading more restart data of increment ', interface_restartInc, ' from file' - call HDF5_read(groupHandle,C_volAvg, 'C_volAvg') - call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc') + call HDF5_read(groupHandle,C_volAvg, 'C_volAvg',.false.) + call MPI_Bcast(C_volAvg,81,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' + call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc',.false.) + call MPI_Bcast(C_volAvgLastInc,81,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index 676252e6d..47ea30d11 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -205,10 +205,18 @@ subroutine grid_mechanical_spectral_polarisation_init fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','r') groupHandle = HDF5_openGroup(fileHandle,'solver') - call HDF5_read(groupHandle,P_aim, 'P_aim') - call HDF5_read(groupHandle,F_aim, 'F_aim') - call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc') - call HDF5_read(groupHandle,F_aimDot, 'F_aimDot') + call HDF5_read(groupHandle,P_aim, 'P_aim',.false.) + call MPI_Bcast(P_aim,9,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' + call HDF5_read(groupHandle,F_aim, 'F_aim',.false.) + call MPI_Bcast(F_aim,9,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' + call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc',.false.) + call MPI_Bcast(F_aim_lastInc,9,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' + call HDF5_read(groupHandle,F_aimDot, 'F_aimDot',.false.) + call MPI_Bcast(F_aimDot,9,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' call HDF5_read(groupHandle,F, 'F') call HDF5_read(groupHandle,F_lastInc, 'F_lastInc') call HDF5_read(groupHandle,F_tau, 'F_tau') @@ -231,7 +239,11 @@ subroutine grid_mechanical_spectral_polarisation_init restartRead2: if (interface_restartInc > 0) then print'(a,i0,a)', ' reading more restart data of increment ', interface_restartInc, ' from file' call HDF5_read(groupHandle,C_volAvg, 'C_volAvg') + call MPI_Bcast(C_volAvg,81,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc') + call MPI_Bcast(C_volAvgLastInc,81,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) + if(ierr /=0) error stop 'MPI error' call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) From 4912342b1be8305aa6f277b3d6b67df2fe44b7dd Mon Sep 17 00:00:00 2001 From: Vitesh Shah Date: Mon, 15 Mar 2021 11:46:30 +0100 Subject: [PATCH 010/219] added missing arguments --- src/grid/grid_mech_FEM.f90 | 4 ++-- src/grid/grid_mech_spectral_polarisation.f90 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index 2980eb65d..aa9e705a6 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -269,10 +269,10 @@ subroutine grid_mechanical_FEM_init restartRead2: if (interface_restartInc > 0) then print'(a,i0,a)', ' reading more restart data of increment ', interface_restartInc, ' from file' - call HDF5_read(groupHandle,C_volAvg, 'C_volAvg') + call HDF5_read(groupHandle,C_volAvg, 'C_volAvg',.false.) call MPI_Bcast(C_volAvg,81,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) if(ierr /=0) error stop 'MPI error' - call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc') + call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc',.false.) call MPI_Bcast(C_volAvgLastInc,81,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) if(ierr /=0) error stop 'MPI error' diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index 47ea30d11..85b70f478 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -238,10 +238,10 @@ subroutine grid_mechanical_spectral_polarisation_init restartRead2: if (interface_restartInc > 0) then print'(a,i0,a)', ' reading more restart data of increment ', interface_restartInc, ' from file' - call HDF5_read(groupHandle,C_volAvg, 'C_volAvg') + call HDF5_read(groupHandle,C_volAvg, 'C_volAvg',.false.) call MPI_Bcast(C_volAvg,81,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) if(ierr /=0) error stop 'MPI error' - call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc') + call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc',.false.) call MPI_Bcast(C_volAvgLastInc,81,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr) if(ierr /=0) error stop 'MPI error' From a7df99e7fc00a266a9d5082443e2cd1ddf487fa4 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 19 Mar 2021 22:35:50 +0100 Subject: [PATCH 011/219] might be helpful at some time --- cmake/Compiler-GNU.cmake | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cmake/Compiler-GNU.cmake b/cmake/Compiler-GNU.cmake index ebba8c0bf..1089e73f1 100644 --- a/cmake/Compiler-GNU.cmake +++ b/cmake/Compiler-GNU.cmake @@ -10,7 +10,7 @@ if (OPENMP) endif () if (OPTIMIZATION STREQUAL "OFF") - set (OPTIMIZATION_FLAGS "-O0" ) + set (OPTIMIZATION_FLAGS "-O0") elseif (OPTIMIZATION STREQUAL "DEFENSIVE") set (OPTIMIZATION_FLAGS "-O2") elseif (OPTIMIZATION STREQUAL "AGGRESSIVE") @@ -117,6 +117,8 @@ set (COMPILE_FLAGS "${COMPILE_FLAGS} -ffpe-summary=all") # Runtime debugging set (DEBUG_FLAGS "${DEBUG_FLAGS} -ffpe-trap=invalid,zero,overflow") # stop execution if floating point exception is detected (NaN is silent) +# Additional options +# -ffpe-trap=precision,denormal,underflow set (DEBUG_FLAGS "${DEBUG_FLAGS} -g") # Generate symbolic debugging information in the object file @@ -126,8 +128,11 @@ set (DEBUG_FLAGS "${DEBUG_FLAGS} -fdump-core") set (DEBUG_FLAGS "${DEBUG_FLAGS} -fcheck=all") # checks for (array-temps,bounds,do,mem,pointer,recursion) -# Additional options -# -ffpe-trap=precision,denormal,underflow +set (DEBUG_FLAGS "${DEBUG_FLAGS} -fstack-protector-all") +# Inserts a guard variable onto the stack frame for all functions + +# Detect memory leaks +# -fsanitize=address #------------------------------------------------------------------------------------------------ # precision settings From b1cca4f5bd4126187ca470634908d04c9ebf5f1a Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Wed, 24 Mar 2021 15:50:39 +0100 Subject: [PATCH 012/219] polishing --- src/IO.f90 | 2 ++ src/YAML_types.f90 | 17 ++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/IO.f90 b/src/IO.f90 index 36b774191..d75f813f2 100644 --- a/src/IO.f90 +++ b/src/IO.f90 @@ -503,6 +503,8 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg) msg = 'Abrupt end of file' case (708) msg = '--- expected after YAML file header' + case (709) + msg = 'Length mismatch' !------------------------------------------------------------------------------------------------- ! errors related to the grid solver diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index b821db34f..88efaf9d1 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -59,21 +59,21 @@ module YAML_types procedure :: & tNode_get_byKey_as1dInt => tNode_get_byKey_as1dInt procedure :: & - tNode_get_byKey_asBool => tNode_get_byKey_asBool + tNode_get_byKey_asBool => tNode_get_byKey_asBool procedure :: & tNode_get_byKey_as1dBool => tNode_get_byKey_as1dBool procedure :: & - tNode_get_byKey_asString => tNode_get_byKey_asString + tNode_get_byKey_asString => tNode_get_byKey_asString procedure :: & tNode_get_byKey_as1dString => tNode_get_byKey_as1dString procedure :: & - getIndex => tNode_get_byKey_asIndex + getIndex => tNode_get_byKey_asIndex procedure :: & - getKey => tNode_getKey_byIndex + getKey => tNode_getKey_byIndex procedure :: & - contains => tNode_contains + contains => tNode_contains procedure :: & - get_as2dFloat => tNode_get_byKey_as2dFloat + get_as2dFloat => tNode_get_byKey_as2dFloat generic :: & get => tNode_get_byIndex, & @@ -1182,9 +1182,12 @@ function tList_as2dFloat(self) row => self%get(1) !SR: some interface called 'shape' may be used? row_data => row%asList() - allocate(tList_as2dFloat(row%length,row_data%length),source=0.0_pReal) + allocate(tList_as2dFloat(self%length,row_data%length),source=0.0_pReal) do i=1,self%length + row => self%get(i) + row_data => row%asList() + if(row_data%length /= size(tList_as2dFloat,2)) call IO_error(709,ext_msg='Varying number of columns') tList_as2dFloat(i,:) = self%get_as1dFloat(i) enddo From 4bf21fcbf5a26fb577494a58ecaccc4af48c76b6 Mon Sep 17 00:00:00 2001 From: Test User Date: Thu, 25 Mar 2021 22:47:53 +0100 Subject: [PATCH 013/219] [skip ci] updated version information after successful test of v3.0.0-alpha2-653-g3d4590a52 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 503e3894e..2a83b7331 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-646-gee8015cd5 +v3.0.0-alpha2-653-g3d4590a52 From 75fb080638b7ac38734bd57dbe88e9c2eeec916e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 08:48:05 +0100 Subject: [PATCH 014/219] old shell scripts - removed unmaintained scripts from 'legacy' - pushed deprecated scripts to 'legacy' --- .gitlab-ci.yml | 55 --- processing/{post => legacy}/DADF5toDREAM3D.py | 0 processing/legacy/addAPS34IDEstrainCoords.py | 51 -- .../addCompatibilityMismatch.py | 0 processing/legacy/addCumulative.py | 48 -- processing/{post => legacy}/addCurl.py | 0 .../{post => legacy}/addDisplacement.py | 0 processing/{post => legacy}/addDivergence.py | 0 processing/legacy/addEhkl.py | 100 ---- .../{post => legacy}/addEuclideanDistance.py | 0 processing/{post => legacy}/addGradient.py | 0 .../{post => legacy}/addSchmidfactors.py | 0 .../{pre => legacy}/geom_grainGrowth.py | 0 .../{pre => legacy}/gmsh_identifySurfaces.py | 0 processing/legacy/imageDataDeformed.py | 194 -------- .../{pre => legacy}/seeds_fromDistribution.py | 0 processing/legacy/vtk2ang.py | 454 ------------------ processing/post/DADF5_postResults.py | 63 --- processing/pre/geom_fromDREAM3D.py | 71 --- processing/pre/geom_fromOsteonGeometry.py | 141 ------ processing/pre/seeds_fromPokes.py | 96 ---- 21 files changed, 1273 deletions(-) rename processing/{post => legacy}/DADF5toDREAM3D.py (100%) delete mode 100755 processing/legacy/addAPS34IDEstrainCoords.py rename processing/{post => legacy}/addCompatibilityMismatch.py (100%) delete mode 100755 processing/legacy/addCumulative.py rename processing/{post => legacy}/addCurl.py (100%) rename processing/{post => legacy}/addDisplacement.py (100%) rename processing/{post => legacy}/addDivergence.py (100%) delete mode 100755 processing/legacy/addEhkl.py rename processing/{post => legacy}/addEuclideanDistance.py (100%) rename processing/{post => legacy}/addGradient.py (100%) rename processing/{post => legacy}/addSchmidfactors.py (100%) rename processing/{pre => legacy}/geom_grainGrowth.py (100%) rename processing/{pre => legacy}/gmsh_identifySurfaces.py (100%) delete mode 100755 processing/legacy/imageDataDeformed.py rename processing/{pre => legacy}/seeds_fromDistribution.py (100%) delete mode 100755 processing/legacy/vtk2ang.py delete mode 100755 processing/post/DADF5_postResults.py delete mode 100755 processing/pre/geom_fromDREAM3D.py delete mode 100755 processing/pre/geom_fromOsteonGeometry.py delete mode 100755 processing/pre/seeds_fromPokes.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5aef9c54c..e16218946 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -105,39 +105,12 @@ pytest_python: - release ################################################################################################### -Pre_SeedGeneration: - stage: deprecated - script: PreProcessing_SeedGeneration/test.py - except: - - master - - release - -Pre_GeomGeneration: - stage: deprecated - script: PreProcessing_GeomGeneration/test.py - except: - - master - - release - -Pre_GeomModification: - stage: deprecated - script: PreProcessing_GeomModification/test.py - except: - - master - - release - Pre_General: stage: deprecated script: PreProcessing/test.py except: - master - release - -Post_General: - stage: deprecated - script: PostProcessing/test.py - except: - - master - release Post_GeometryReconstruction: @@ -147,27 +120,6 @@ Post_GeometryReconstruction: - master - release -Post_addCurl: - stage: deprecated - script: addCurl/test.py - except: - - master - - release - -Post_addDivergence: - stage: deprecated - script: addDivergence/test.py - except: - - master - - release - -Post_addGradient: - stage: deprecated - script: addGradient/test.py - except: - - master - - release - Post_OrientationAverageMisorientation: stage: deprecated script: @@ -262,13 +214,6 @@ pytest_fortran: - master - release -Plasticity_DetectChanges: - stage: grid - script: Plasticity_DetectChanges/test.py - except: - - master - - release - Phenopowerlaw_singleSlip: stage: grid script: Phenopowerlaw_singleSlip/test.py diff --git a/processing/post/DADF5toDREAM3D.py b/processing/legacy/DADF5toDREAM3D.py similarity index 100% rename from processing/post/DADF5toDREAM3D.py rename to processing/legacy/DADF5toDREAM3D.py diff --git a/processing/legacy/addAPS34IDEstrainCoords.py b/processing/legacy/addAPS34IDEstrainCoords.py deleted file mode 100755 index 465f03e4e..000000000 --- a/processing/legacy/addAPS34IDEstrainCoords.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -from io import StringIO -from optparse import OptionParser - -import numpy as np - -import damask - - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - - -# -------------------------------------------------------------------- -# MAIN -# -------------------------------------------------------------------- - -parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [ASCIItable(s)]', description = """ -Transform X,Y,Z,F APS BeamLine 34 coordinates to x,y,z APS strain coordinates. - -""", version = scriptID) - -parser.add_option('-f','--frame',dest='frame', metavar='string', - help='label of APS X,Y,Z coords') -parser.add_option('--depth', dest='depth', metavar='string', - help='depth') - -(options,filenames) = parser.parse_args() -if filenames == []: filenames = [None] - -if options.frame is None: - parser.error('frame not specified') -if options.depth is None: - parser.error('depth not specified') - - -rot_to_TSL = damask.Rotation.from_axis_angle([-1,0,0,.75*np.pi]) - -for name in filenames: - damask.util.report(scriptName,name) - - table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - - coord = - table.get(options.frame) - coord[:,2] += table.get(options.depth)[:,0] - - table.add('coord',rot_to_TSL.broadcast_to(coord.shape[0]) @ coord,scriptID+' '+' '.join(sys.argv[1:]))\ - .save((sys.stdout if name is None else name),legacy=True) diff --git a/processing/post/addCompatibilityMismatch.py b/processing/legacy/addCompatibilityMismatch.py similarity index 100% rename from processing/post/addCompatibilityMismatch.py rename to processing/legacy/addCompatibilityMismatch.py diff --git a/processing/legacy/addCumulative.py b/processing/legacy/addCumulative.py deleted file mode 100755 index 3ba527acd..000000000 --- a/processing/legacy/addCumulative.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -from io import StringIO -from optparse import OptionParser - -import numpy as np - -import damask - - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - - -# -------------------------------------------------------------------- -# MAIN -# -------------------------------------------------------------------- - -parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [ASCIItable(s)]', description = """ -Add cumulative (sum of first to current row) values for given label(s). -""", version = scriptID) - -parser.add_option('-l','--label', - dest='labels', - action = 'extend', metavar = '', - help = 'columns to cumulate') -parser.add_option('-p','--product', - dest='product', action = 'store_true', - help = 'product of values instead of sum') - -(options,filenames) = parser.parse_args() -if filenames == []: filenames = [None] - -if options.labels is None: - parser.error('no data column(s) specified.') - -for name in filenames: - damask.util.report(scriptName,name) - - table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - for label in options.labels: - table = table.add('cum_{}({})'.format('prod' if options.product else 'sum',label), - np.cumprod(table.get(label),0) if options.product else np.cumsum(table.get(label),0), - scriptID+' '+' '.join(sys.argv[1:])) - - table.save((sys.stdout if name is None else name),legacy=True) diff --git a/processing/post/addCurl.py b/processing/legacy/addCurl.py similarity index 100% rename from processing/post/addCurl.py rename to processing/legacy/addCurl.py diff --git a/processing/post/addDisplacement.py b/processing/legacy/addDisplacement.py similarity index 100% rename from processing/post/addDisplacement.py rename to processing/legacy/addDisplacement.py diff --git a/processing/post/addDivergence.py b/processing/legacy/addDivergence.py similarity index 100% rename from processing/post/addDivergence.py rename to processing/legacy/addDivergence.py diff --git a/processing/legacy/addEhkl.py b/processing/legacy/addEhkl.py deleted file mode 100755 index 04c42deb5..000000000 --- a/processing/legacy/addEhkl.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -from optparse import OptionParser - -import numpy as np - -import damask - - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - -def normalize(vec): - return vec/np.sqrt(np.inner(vec,vec)) - -def E_hkl(stiffness,vec): # stiffness = (c11,c12,c44) - v = normalize(vec) - S11 = (stiffness[0]+stiffness[1])/(stiffness[0]*stiffness[0]+stiffness[0]*stiffness[1]-2.0*stiffness[1]*stiffness[1]) - S12 = ( -stiffness[1])/(stiffness[0]*stiffness[0]+stiffness[0]*stiffness[1]-2.0*stiffness[1]*stiffness[1]) - S44 = 1.0/stiffness[2] - - invE = S11-(S11-S12-0.5*S44)* (1.0 - \ - (v[0]**4+v[1]**4+v[2]**4) \ - /#------------------------------------ - np.inner(v,v)**2 \ - ) - - return 1.0/invE - - -# -------------------------------------------------------------------- -# MAIN -# -------------------------------------------------------------------- - -parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [ASCIItable(s)]', description = """ -Add column(s) containing directional stiffness based on given cubic stiffness values C11, C12, and C44 in consecutive columns. - -""", version = scriptID) - -parser.add_option('-c','--stiffness', - dest = 'stiffness', - action = 'extend', metavar = '', - help = 'heading of column containing C11 (followed by C12, C44) field values') -parser.add_option('-d','--direction','--hkl', - dest = 'hkl', - type = 'int', nargs = 3, metavar = 'int int int', - help = 'direction of elastic modulus [%default]') -parser.set_defaults(hkl = (1,1,1), - ) - -(options,filenames) = parser.parse_args() - -if options.stiffness is None: - parser.error('no data column specified...') - -# --- loop over input files ------------------------------------------------------------------------- - -if filenames == []: filenames = [None] - -for name in filenames: - try: - table = damask.ASCIItable(name = name) - except IOError: - continue - damask.util.report(scriptName,name) - -# ------------------------------------------ read header ------------------------------------------ - - table.head_read() - -# ------------------------------------------ sanity checks ---------------------------------------- - - remarks = [] - columns = [] - - for i,column in enumerate(table.label_index(options.stiffness)): - if column < 0: remarks.append('column {} not found.'.format(options.stiffness[i])) - else: - columns.append(column) - table.labels_append(['E{}{}{}({arg2})'.format(*options.hkl,arg2=options.stiffness[i])]) # extend ASCII header with new labels - - if remarks != []: damask.util.croak(remarks) - -# ------------------------------------------ assemble header -------------------------------------- - - table.info_append(scriptID + '\t' + ' '.join(sys.argv[1:])) - table.head_write() - -# ------------------------------------------ process data ------------------------------------------ - outputAlive = True - while outputAlive and table.data_read(): # read next data line of ASCII table - for column in columns: - table.data_append(E_hkl(list(map(float,table.data[column:column+3])),options.hkl)) - outputAlive = table.data_write() # output processed line - -# ------------------------------------------ output finalization ----------------------------------- - - table.close() # close ASCII tables diff --git a/processing/post/addEuclideanDistance.py b/processing/legacy/addEuclideanDistance.py similarity index 100% rename from processing/post/addEuclideanDistance.py rename to processing/legacy/addEuclideanDistance.py diff --git a/processing/post/addGradient.py b/processing/legacy/addGradient.py similarity index 100% rename from processing/post/addGradient.py rename to processing/legacy/addGradient.py diff --git a/processing/post/addSchmidfactors.py b/processing/legacy/addSchmidfactors.py similarity index 100% rename from processing/post/addSchmidfactors.py rename to processing/legacy/addSchmidfactors.py diff --git a/processing/pre/geom_grainGrowth.py b/processing/legacy/geom_grainGrowth.py similarity index 100% rename from processing/pre/geom_grainGrowth.py rename to processing/legacy/geom_grainGrowth.py diff --git a/processing/pre/gmsh_identifySurfaces.py b/processing/legacy/gmsh_identifySurfaces.py similarity index 100% rename from processing/pre/gmsh_identifySurfaces.py rename to processing/legacy/gmsh_identifySurfaces.py diff --git a/processing/legacy/imageDataDeformed.py b/processing/legacy/imageDataDeformed.py deleted file mode 100755 index b9219ac47..000000000 --- a/processing/legacy/imageDataDeformed.py +++ /dev/null @@ -1,194 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -from optparse import OptionParser - -import numpy as np -from PIL import Image, ImageDraw - -import damask - - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - - -# -------------------------------------------------------------------- -# MAIN -# -------------------------------------------------------------------- - -parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [file[s]]', description = """ -Generate PNG image from scalar data on grid deformed by (periodic) deformation gradient. - -""", version = scriptID) - -parser.add_option('-l','--label', - dest = 'label', - type = 'string', metavar = 'string', - help = 'column containing data [all]') -parser.add_option('-r','--range', - dest = 'range', - type = 'float', nargs = 2, metavar = 'float float', - help = 'data range (min max) [auto]') -parser.add_option('--gap', '--transparent', - dest = 'gap', - type = 'float', metavar = 'float', - help = 'value to treat as transparent [%default]') -parser.add_option('-d','--dimension', - dest = 'dimension', - type = 'int', nargs = 3, metavar = ' '.join(['int']*3), - help = 'data dimension (x/y/z)') -parser.add_option('-s','--size', - dest = 'size', - type = 'float', nargs = 3, metavar = ' '.join(['float']*3), - help = 'box size (x/y/z)') -parser.add_option('-f','--defgrad', - dest = 'defgrad', metavar = 'string', - help = 'column label of deformation gradient [%default]') -parser.add_option('--scaling', - dest = 'scaling', - type = 'float', nargs = 3, metavar = ' '.join(['float']*3), - help = 'x/y/z scaling of displacement fluctuation [%default]') -parser.add_option('-z','--layer', - dest = 'z', - type = 'int', metavar = 'int', - help = 'index of z plane to plot [%default]') -parser.add_option('--color', - dest = 'color', - type = 'string', metavar = 'string', - help = 'color scheme') -parser.add_option('--invert', - dest = 'invert', - action = 'store_true', - help = 'invert color scheme') -parser.add_option('--abs', - dest = 'abs', - action = 'store_true', - help = 'magnitude of values') -parser.add_option('--log', - dest = 'log', - action = 'store_true', - help = 'log10 of values') -parser.add_option('-N','--pixelsize', - dest = 'pixelsize', - type = 'int', metavar = 'int', - help = 'pixels per cell edge') -parser.add_option('--show', - dest = 'show', - action = 'store_true', - help = 'show resulting image') - -parser.set_defaults(label = None, - range = [0.0,0.0], - dimension = [], - size = [], - z = 1, - abs = False, - log = False, - defgrad = 'f', - scaling = [1.,1.,1.], - color = "gray", - invert = False, - pixelsize = 1, - show = False, - ) - -(options,filenames) = parser.parse_args() -if filenames == []: filenames = [None] - -options.size = np.array(options.size) -options.dimension = np.array(options.dimension) -options.range = np.array(options.range) - -if options.z > 0: options.z -= 1 # adjust to 0-based indexing - -# --- color palette --------------------------------------------------------------------------------- - -theMap = damask.Colormap(predefined=options.color) -if options.invert: theMap = theMap.invert() -theColors = np.uint8(np.array(theMap.export(format='list',steps=256))*255) - -# --- loop over input files ------------------------------------------------------------------------- -for name in filenames: - try: - table = damask.ASCIItable(name = name, labeled = options.label is not None, readonly = True) - except IOError: - continue - damask.util.report(scriptName,name) - -# ------------------------------------------ read header ------------------------------------------ - - table.head_read() - -# --------------- figure out columns to process --------------------------------------------------- - - errors = [] - if table.label_dimension(options.label) != 1: - errors.append('no scalar data ({}) found.'.format(options.label)) - if table.label_dimension(options.defgrad) != 9: - errors.append('no deformation gradient tensor (1..9_{}) found.'.format(options.defgrad)) - - if errors != []: - table.croak('\n'.join(errors)+'\n') - table.close(dismiss = True) - continue - - table.data_readArray([options.label,options.defgrad]) - - data = table.data[:,0 ].transpose().reshape( list(options.dimension),order='F') - F = table.data[:,1:10].transpose().reshape([3,3]+list(options.dimension),order='F') - - if options.abs: data = np.abs(data) - if options.log: data = np.log10(data) - if np.all(options.range == 0.0): options.range = np.array([data.min(),data.max()]) - elif options.log: options.range = np.log10(options.range) - - data = ( data - options.range.min()) / \ - (options.range.max() - options.range.min()) # data scaled to fraction of range - - data = np.clip(data,0.0,1.0) # cut off outliers (should be none) - -# ---------------- calculate coordinates ----------------------------------------------------------- - - Favg = damask.core.math.tensorAvg(F) - centroids = damask.core.mesh.deformedCoordsFFT(options.size,F,Favg,options.scaling) - nodes = damask.core.mesh.nodesAroundCentres(options.size,Favg,centroids) - - boundingBox = np.array([ \ - [np.amin(nodes[0,:,:,options.z]),np.amin(nodes[1,:,:,options.z]),np.amin(nodes[2,:,:,options.z])], - [np.amax(nodes[0,:,:,options.z]),np.amax(nodes[1,:,:,options.z]),np.amax(nodes[2,:,:,options.z])], - ]) # find x-y bounding box for given z layer - - nodes -= boundingBox[0].repeat(np.prod(options.dimension+1)).reshape([3]+list(options.dimension+1)) - nodes *= (options.pixelsize*options.dimension/options.size).repeat(np.prod(options.dimension+1)).\ - reshape([3]+list(options.dimension+1)) - imagesize = (options.pixelsize*(boundingBox[1]-boundingBox[0])* # determine image size from number of - options.dimension/options.size)[:2].astype('i') # cells in overall bounding box - im = Image.new('RGBA',imagesize) - draw = ImageDraw.Draw(im) - - for y in range(options.dimension[1]): - for x in range(options.dimension[0]): - draw.polygon([nodes[0,x ,y ,options.z], - nodes[1,x ,y ,options.z], - nodes[0,x+1,y ,options.z], - nodes[1,x+1,y ,options.z], - nodes[0,x+1,y+1,options.z], - nodes[1,x+1,y+1,options.z], - nodes[0,x ,y+1,options.z], - nodes[1,x ,y+1,options.z], - ], - fill = tuple(theColors[int(255*data[x,y,options.z])], - 0 if data[x,y,options.z] == options.gap else 255), - outline = None) - -# ------------------------------------------ output result ----------------------------------------- - - im.save(os.path.splitext(name)[0]+ \ - ('_'+options.label if options.label else '')+ \ - '.png' if name else sys.stdout, - format = "PNG") - - table.close() # close ASCII table - if options.show: im.show() diff --git a/processing/pre/seeds_fromDistribution.py b/processing/legacy/seeds_fromDistribution.py similarity index 100% rename from processing/pre/seeds_fromDistribution.py rename to processing/legacy/seeds_fromDistribution.py diff --git a/processing/legacy/vtk2ang.py b/processing/legacy/vtk2ang.py deleted file mode 100755 index 7991251fb..000000000 --- a/processing/legacy/vtk2ang.py +++ /dev/null @@ -1,454 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -from optparse import OptionParser -import string -import math - -import numpy as np -import vtk - -import damask - - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - -# ----------------------------- -def getHeader(filename,sizeFastIndex,sizeSlowIndex,stepsize): - """Returns header for ang file step size in micrometer.""" - return '\n'.join([ - '# TEM_PIXperUM 1.000000', - '# x-star 1.000000', - '# y-star 1.000000', - '# z-star 1.000000', - '# WorkingDistance 18.000000', - '#', - '# Phase 1', - '# MaterialName XX', - '# Formula XX', - '# Info', - '# Symmetry 43', - '# LatticeConstants 2.870 2.870 2.870 90.000 90.000 90.000', - '# NumberFamilies 1', - '# hklFamilies 1 1 0 1 0.000000 1', - '# Categories 0 0 0 0 0 ', - '#', - '# GRID: SqrGrid', - '# XSTEP: ' + str(stepsize*1e6), - '# YSTEP: ' + str(stepsize*1e6), - '# NCOLS_ODD: ' + str(sizeFastIndex), - '# NCOLS_EVEN: ' + str(sizeFastIndex), - '# NROWS: ' + str(sizeSlowIndex), - '#', - '# OPERATOR: ' + string.replace('$Id$','\n','\\n'), - '#', - '# SAMPLEID: {}'.format(filename), - '#', - '# SCANID: ', - '#', - ]) + '\n' - - -# ----------------------------- -def positiveRadians(angle): - """Returns positive angle in radians from angle in degrees.""" - return math.radians(float(angle)) % (2.*math.pi) - - -# ----------------------------- -def getDataLine(angles,x,y,validData=True): - """ - Returns string of one line in ang file. - - Convention in ang file: y coordinate comes first and is fastest index - positions in micrometer. - """ - info = {True: (9999.9, 1.0, 0,99999,0.0), - False: ( -1.0,-1.0,-1, -1,1.0)} - return '%9.5f %9.5f %9.5f %12.5f %12.5f %6.1f %6.3f %2i %6i %6.3f \n'\ - %(tuple(map(positiveRadians,angles))+(y*1e6,x*1e6)+info[validData]) - - -# -------------------------------------------------------------------- -# MAIN FUNCTION STARTS HERE -# -------------------------------------------------------------------- -parser = OptionParser(usage='%prog options [file[s]]', description = """ -Builds a ang files from a vtk file. - -""", version = scriptID) - - -parser.add_option('--disp','--displacement',dest='dispLabel', - metavar ='string', - help='label of displacements [%default]') -parser.add_option('--euler', dest='eulerLabel', nargs=3, - metavar ='string string string', - help='labels of euler angles [%default]') -parser.add_option('-n','--normal', dest='normal', type='float', nargs=3, - metavar ='float float float', - help='normal of slices in direction of increasing slice numbers [%default]') -parser.add_option('-u','--up', dest='up', type='float', nargs=3, - metavar ='float float float', - help='up direction of slices [%default]') -parser.add_option('-i','--slices', dest='Nslices', type='int', - metavar ='int', - help='number of slices [%default]') -parser.add_option('-d','--distance', dest='distance', type='float', - metavar ='float', - help='slice distance [%default]') -parser.add_option('-s','--scale', dest='scale', type='float', - metavar ='float', - help='scale length from vtk file [%default]') -parser.add_option('-r','--resolution', dest='resolution', type='float', - metavar ='float', - help='scaling factor for resolution [%default]') -parser.add_option('--verbose', dest='verbose', action='store_true', - help='verbose mode') -parser.add_option('--visualize', dest='visualize', action='store_true', - help='visualize geometry') - -parser.set_defaults(dispLabel = 'displacement') -parser.set_defaults(eulerLabel = ['1_1_eulerangles','1_2_eulerangles','1_3_eulerangles']) -parser.set_defaults(normal = [0.0,0.0,-1.0]) -parser.set_defaults(up = [0.0,1.0,0.0]) -parser.set_defaults(Nslices = 1) -parser.set_defaults(distance = 0.0) -parser.set_defaults(scale = 1.0) -parser.set_defaults(resolution = 1.0) -parser.set_defaults(dispScaling = 1.0) -parser.set_defaults(verbose = False) -parser.set_defaults(visualize = False) -(options,filenames) = parser.parse_args() - - -#--- SANITY CHECKS - -# check for valid filenames - -for filename in filenames: - if not os.path.exists(filename): - parser.error('file "%s" does not exist'%filename) - if not os.path.splitext(filename)[1] == '.vtk': - parser.error('"%s": need vtk file'%filename) - - -# check for othogonality of normal and up vector - -if np.dot(np.array(options.normal),np.array(options.up)) > 1e-3: - parser.error('normal vector and up vector have to be orthogonal') - - -#--- ITERATE OVER FILES AND PROCESS THEM - -for filename in filenames: - - if options.verbose: sys.stdout.write("\nREADING VTK FILE\n") -# Read the source file - reader = vtk.vtkUnstructuredGridReader() - reader.SetFileName(filename) - reader.ReadAllScalarsOn() - reader.ReadAllVectorsOn() - reader.Update() - undeformedMesh = reader.GetOutput() - - -# Get euler angles from cell data - - if options.verbose: sys.stdout.write("\nGETTING EULER ANGLES\n") - angles = {} - for i in range(undeformedMesh.GetPointData().GetNumberOfArrays()): - scalarName = undeformedMesh.GetPointData().GetArrayName(i) - if scalarName in options.eulerLabel: - angles[scalarName] = undeformedMesh.GetCellData().GetScalars(scalarName) - if options.verbose: sys.stdout.write(" found scalar with name %s\n"%scalarName) - if len(angles) < 3: # found data for all three euler angles? - for label in options.eulerLabel: - if label not in angles.keys(): - parser.error('Could not find scalar data with name %s'%label) - - -# Get deformed mesh - - if options.verbose: sys.stdout.write("\nDEFORM MESH\n") - warpVector = vtk.vtkWarpVector() - undeformedMesh.GetPointData().SetActiveVectors(options.dispLabel) - warpVector.SetInputData(undeformedMesh) - warpVector.Update() - deformedMesh = warpVector.GetOutput() - box = deformedMesh.GetBounds() # bounding box in mesh system - if options.verbose: - sys.stdout.write(" bounding box in lab system\n") - sys.stdout.write(" x (% .8f % .8f)\n"%(box[0],box[1])) - sys.stdout.write(" y (% .8f % .8f)\n"%(box[2],box[3])) - sys.stdout.write(" z (% .8f % .8f)\n"%(box[4],box[5])) - - -# Get cell centers of deformed mesh (position of ips) - - if options.verbose: sys.stdout.write("\nGETTING CELL CENTERS OF DEFORMED MESH\n") - cellCenter = vtk.vtkCellCenters() - cellCenter.SetVertexCells(0) # do not generate vertex cells, just points - cellCenter.SetInputData(deformedMesh) - cellCenter.Update() - meshIPs = cellCenter.GetOutput() - - -# Get outer surface of deformed mesh - - if options.verbose: sys.stdout.write("\nGETTING OUTER SURFACE OF DEFORMED MESH\n") - surfaceFilter = vtk.vtkDataSetSurfaceFilter() - surfaceFilter.SetInputData(deformedMesh) - surfaceFilter.Update() - surface = surfaceFilter.GetOutput() - - -# Get coordinate system for ang files -# z-vector is normal to slices -# x-vector corresponds to the up-direction -# "R" rotates coordinates from the mesh system into the TSL system - - if options.verbose: sys.stdout.write("\nGETTING COORDINATE SYSTEM FOR ANG FILES\n") - z = np.array(options.normal,dtype='float') - z = z / np.linalg.norm(z) - x = np.array(options.up,dtype='float') - x = x / np.linalg.norm(x) - y = np.cross(z,x) - R = np.array([x,y,z]) - if options.verbose: - sys.stdout.write(" axis (x: up direction, z: slice normal)\n") - sys.stdout.write(" x (% .8f % .8f % .8f)\n"%tuple(x)) - sys.stdout.write(" y (% .8f % .8f % .8f)\n"%tuple(y)) - sys.stdout.write(" z (% .8f % .8f % .8f)\n"%tuple(z)) - - -# Get bounding box in rotated system (x,y,z) - - if options.verbose: sys.stdout.write("\nGETTING BOUNDING BOX IN ROTATED SYSTEM\n") - rotatedbox = [[np.inf,-np.inf] for i in range(3)] # bounding box in rotated TSL system - for n in range(8): # loop over eight vertices of mesh bounding box - vert = np.array([box[0+(n//1)%2], - box[2+(n//2)%2], - box[4+(n//4)%2]]) # vertex in mesh system - rotatedvert = np.dot(R,vert) # vertex in rotated system - for i in range(3): - rotatedbox[i][0] = min(rotatedbox[i][0],rotatedvert[i]) - rotatedbox[i][1] = max(rotatedbox[i][1],rotatedvert[i]) - if options.verbose: - sys.stdout.write(" bounding box in rotated system\n") - sys.stdout.write(" x (% .8f % .8f)\n"%tuple(rotatedbox[0])) - sys.stdout.write(" y (% .8f % .8f)\n"%tuple(rotatedbox[1])) - sys.stdout.write(" z (% .8f % .8f)\n"%tuple(rotatedbox[2])) - - -# Correct bounding box so that a multiplicity of the resolution fits into it -# and get number of points and extent in each (rotated) axis direction - - if options.verbose: sys.stdout.write("\nCORRECTING EXTENT OF BOUNDING BOX IN ROTATED SYSTEM\n") - correction = [] - Npoints = [] - extent = [rotatedbox[i][1] - rotatedbox[i][0] for i in range(3)] - for i in range(2): - Npoints.extend([int(math.ceil(extent[i] / options.resolution))]) - correction.extend([float(Npoints[i]) * options.resolution - extent[i]]) - if options.distance > 0.0: - Npoints.extend([int(math.ceil(extent[2] / options.distance))]) - correction.extend([float(Npoints[2]) * options.distance - extent[2]]) - else: - Npoints.extend([options.Nslices]) - correction.extend([0.0]) - options.distance = extent[2] / float(options.Nslices) - for i in range(3): - rotatedbox[i][0] -= 0.5 * correction[i] - rotatedbox[i][1] += 0.5 * correction[i] - extent[i] = rotatedbox[i][1] - rotatedbox[i][0] - NpointsPerSlice = Npoints[0] * Npoints[1] - totalNpoints = NpointsPerSlice * Npoints[2] - if options.verbose: - sys.stdout.write(" corrected bounding box in rotated system\n") - sys.stdout.write(" x (% .8f % .8f)\n"%tuple(rotatedbox[0])) - sys.stdout.write(" y (% .8f % .8f)\n"%tuple(rotatedbox[1])) - sys.stdout.write(" z (% .8f % .8f)\n"%tuple(rotatedbox[2])) - - -# Generate new regular point grid for ang files -# Use "polydata" object with points as single vertices -# beware of TSL convention: y direction is fastest index - - if options.verbose: sys.stdout.write("\nGENERATING POINTS FOR POINT GRID") - points = vtk.vtkPoints() - for k in range(Npoints[2]): - for j in range(Npoints[0]): - for i in range(Npoints[1]): # y is fastest index - rotatedpoint = np.array([rotatedbox[0][0] + (float(j) + 0.5) * options.resolution, - rotatedbox[1][0] + (float(i) + 0.5) * options.resolution, - rotatedbox[2][0] + (float(k) + 0.5) * options.distance ]) # point in rotated system - point = np.dot(R.T,rotatedpoint) # point in mesh system - points.InsertNextPoint(list(point)) - if options.verbose: - sys.stdout.write("\rGENERATING POINTS FOR POINT GRID %d%%" %(100*(Npoints[1]*(k*Npoints[0]+j)+i+1)/totalNpoints)) - sys.stdout.flush() - if options.verbose: - sys.stdout.write("\n number of slices: %i\n"%Npoints[2]) - sys.stdout.write(" slice spacing: %.8f\n"%options.distance) - if Npoints[2] > 1: - sys.stdout.write(" number of points per slice: %i = %i rows * %i points in row\n"%(NpointsPerSlice,Npoints[0],Npoints[1])) - sys.stdout.write(" grid resolution: %.8f\n"%options.resolution) - - if options.verbose: sys.stdout.write("\nGENERATING VERTICES FOR POINT GRID") - vertices = vtk.vtkCellArray() - for i in range(totalNpoints): - vertex = vtk.vtkVertex() - vertex.GetPointIds().SetId(0,i) # each vertex consists of exactly one (index 0) point with ID "i" - vertices.InsertNextCell(vertex) - if options.verbose: - sys.stdout.write("\rGENERATING VERTICES FOR POINT GRID %d%%" %(100*(i+1)/totalNpoints)) - sys.stdout.flush() - - if options.verbose: sys.stdout.write("\n\nGENERATING POINT GRID\n") - pointgrid = vtk.vtkPolyData() - pointgrid.SetPoints(points) - pointgrid.SetVerts(vertices) - pointgrid.Update() - - -# Find out which points reside inside mesh geometry - - if options.verbose: sys.stdout.write("\nIDENTIFYING POINTS INSIDE MESH GEOMETRY\n") - enclosedPoints = vtk.vtkSelectEnclosedPoints() - enclosedPoints.SetSurface(surface) - enclosedPoints.SetInput(pointgrid) - enclosedPoints.Update() - - -# Build kdtree from mesh IPs and match mesh IPs to point grid - - if options.verbose: sys.stdout.write("\nBUILDING MAPPING OF GRID POINTS") - kdTree = vtk.vtkKdTree() - kdTree.BuildLocatorFromPoints(meshIPs.GetPoints()) - gridToMesh = [] - ids = vtk.vtkIdList() - NenclosedPoints = 0 - for i in range(pointgrid.GetNumberOfPoints()): - gridToMesh.append([]) - if enclosedPoints.IsInside(i): - NenclosedPoints += 1 -# here one could use faster(?) "FindClosestPoint" if only first nearest neighbor required - kdTree.FindClosestNPoints(1,pointgrid.GetPoint(i),ids) - for j in range(ids.GetNumberOfIds()): - gridToMesh[-1].extend([ids.GetId(j)]) - if options.verbose: - sys.stdout.write("\rBUILDING MAPPING OF GRID POINTS %d%%" %(100*(i+1)/totalNpoints)) - sys.stdout.flush() - if options.verbose: - sys.stdout.write("\n Number of points inside mesh geometry %i\n"%NenclosedPoints) - sys.stdout.write(" Number of points outside mesh geometry %i\n"%(totalNpoints - NenclosedPoints)) - - - -# ITERATE OVER SLICES AND CREATE ANG FILE - - if options.verbose: - sys.stdout.write("\nWRITING OUT ANG FILES\n") - sys.stdout.write(" scaling all length with %f\n"%options.scale) - x0,y0,z0 = np.dot(R,pointgrid.GetPoint(0)) # first point on slice defines origin - for sliceN in range(Npoints[2]): - - # Open file and write header - - angfilename = eval('"'+eval("'%%s_slice%%0%ii.ang'%(math.log10(Npoints[2])+1)")+'"%(os.path.splitext(filename)[0],sliceN+1)') - with open(angfilename,'w') as angfile: - if options.verbose: sys.stdout.write(" %s\n"%angfilename) - angfile.write(getHeader(filename,Npoints[1],Npoints[0],options.resolution*options.scale)) - for i in range(sliceN*NpointsPerSlice,(sliceN+1)*NpointsPerSlice): # Iterate over points on slice - - - # Get euler angles of closest IDs - - if enclosedPoints.IsInside(i): - phi = [] - for j in range(len(gridToMesh[i])): - IP = gridToMesh[i][j] - phi.append([]) - for k in range(3): - phi[-1].extend([angles[options.eulerLabel[k]].GetValue(IP)]) - else: - phi = [[720,720,720]] # fake angles - - - # Interpolate Euler angle - # NOT YET IMPLEMENTED, simply take the nearest neighbors values - - interpolatedPhi = phi[0] - - - # write data to ang file - - x,y,z = np.dot(R,pointgrid.GetPoint(i)) # point in rotated TSL system - x -= x0 # first point on slice defines origin - y -= y0 # first point on slice defines origin - x *= options.scale - y *= options.scale - angfile.write(getDataLine(interpolatedPhi,x,y,enclosedPoints.IsInside(i))) - - -# Visualize slices - - if options.visualize: - meshMapper = vtk.vtkDataSetMapper() - meshMapper.SetInput(surface) - meshMapper.ScalarVisibilityOff() # do not use scalar data for coloring - meshActor = vtk.vtkActor() - meshActor.SetMapper(meshMapper) - meshActor.GetProperty().SetOpacity(0.2) - meshActor.GetProperty().SetColor(1.0,1.0,0) - meshActor.GetProperty().BackfaceCullingOn() - - boxpoints = vtk.vtkPoints() - for n in range(8): - P = [rotatedbox[0][(n/1)%2], - rotatedbox[1][(n/2)%2], - rotatedbox[2][(n/4)%2]] - boxpoints.InsertNextPoint(list(np.dot(R.T,np.array(P)))) - box = vtk.vtkHexahedron() - for n,i in enumerate([0,1,3,2,4,5,7,6]): - box.GetPointIds().SetId(n,i) - boxgrid = vtk.vtkUnstructuredGrid() - boxgrid.SetPoints(boxpoints) - boxgrid.InsertNextCell(box.GetCellType(), box.GetPointIds()) - boxsurfaceFilter = vtk.vtkDataSetSurfaceFilter() - boxsurfaceFilter.SetInput(boxgrid) - boxsurfaceFilter.Update() - boxsurface = boxsurfaceFilter.GetOutput() - - boxMapper = vtk.vtkDataSetMapper() - boxMapper.SetInput(boxsurface) - boxActor = vtk.vtkActor() - boxActor.SetMapper(boxMapper) - boxActor.GetProperty().SetLineWidth(2.0) - boxActor.GetProperty().SetRepresentationToWireframe() - - gridMapper = vtk.vtkDataSetMapper() - gridMapper.SetInput(pointgrid) - gridActor = vtk.vtkActor() - gridActor.SetMapper(gridMapper) - gridActor.GetProperty().SetColor(0,0,0) - gridActor.GetProperty().SetPointSize(3) - - - renderer = vtk.vtkRenderer() - renderWindow = vtk.vtkRenderWindow() - renderWindow.FullScreenOn() - renderWindow.AddRenderer(renderer) - renderWindowInteractor = vtk.vtkRenderWindowInteractor() - renderWindowInteractor.SetRenderWindow(renderWindow) - renderer.AddActor(meshActor) - renderer.AddActor(boxActor) - renderer.AddActor(gridActor) - renderer.SetBackground(1,1,1) - - renderWindow.Render() - renderWindowInteractor.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera()) - renderWindowInteractor.Start() - diff --git a/processing/post/DADF5_postResults.py b/processing/post/DADF5_postResults.py deleted file mode 100755 index 58d82c2e2..000000000 --- a/processing/post/DADF5_postResults.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python3 - -import os -import argparse - -import numpy as np - -import damask - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - -# -------------------------------------------------------------------- -# MAIN -# -------------------------------------------------------------------- -parser = argparse.ArgumentParser() - -parser.add_argument('filenames', nargs='+', - help='DADF5 files') -parser.add_argument('-d','--dir', dest='dir',default='postProc',metavar='string', - help='name of subdirectory relative to the location of the DADF5 file to hold output') -parser.add_argument('--mat', nargs='+', - help='labels for homogenization',dest='mat') -parser.add_argument('--con', nargs='+', - help='labels for phase',dest='con') - -options = parser.parse_args() - -if options.mat is None: options.mat=[] -if options.con is None: options.con=[] - -for filename in options.filenames: - results = damask.Result(filename) - - if not results.structured: continue - coords = damask.grid_filters.coordinates0_point(results.cells,results.size,results.origin).reshape(-1,3,order='F') - - N_digits = int(np.floor(np.log10(int(results.increments[-1][10:]))))+1 - N_digits = 5 # hack to keep test intact - for inc in damask.util.show_progress(results.iterate('increments'),len(results.increments)): - table = damask.Table(np.ones(np.product(results.cells),dtype=int)*int(inc[10:]),{'inc':(1,)})\ - .add('pos',coords.reshape(-1,3)) - - results.view('homogenizations',False) - results.view('phases',True) - for label in options.con: - x = results.get_dataset_location(label) - if len(x) != 0: - table = table.add(label,results.read_dataset(x,0,plain=True).reshape(results.cells.prod(),-1)) - - results.view('phases',False) - results.view('homogenizations',True) - for label in options.mat: - x = results.get_dataset_location(label) - if len(x) != 0: - table = table.add(label,results.read_dataset(x,0,plain=True).reshape(results.cells.prod(),-1)) - - dirname = os.path.abspath(os.path.join(os.path.dirname(filename),options.dir)) - if not os.path.isdir(dirname): - os.mkdir(dirname,0o755) - file_out = '{}_inc{}.txt'.format(os.path.splitext(os.path.split(filename)[-1])[0], - inc[10:].zfill(N_digits)) - table.save(os.path.join(dirname,file_out),legacy=True) diff --git a/processing/pre/geom_fromDREAM3D.py b/processing/pre/geom_fromDREAM3D.py deleted file mode 100755 index e4840fc80..000000000 --- a/processing/pre/geom_fromDREAM3D.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python3 - -import os -from optparse import OptionParser - -import damask - - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - - -#-------------------------------------------------------------------------------------------------- -# MAIN -#-------------------------------------------------------------------------------------------------- - -parser = OptionParser(usage='%prog options [DREAM.3Dfile(s)]', description = """ -Converts DREAM.3D file. Input can be cell data (direct pointwise takeover) or grain data (individual -grains are segmented). Requires orientation data as quaternion. - -""", version = scriptID) - -parser.add_option('-b','--basegroup', - dest = 'basegroup', - metavar = 'string', - help = 'name of the group in "DataContainers" containing the pointwise (and, if applicable grain average) data') -parser.add_option('-p','--pointwise', - dest = 'pointwise', - metavar = 'string', - help = 'name of the group in "DataContainers/" containing pointwise data [%default]') -parser.add_option('-a','--average', - dest = 'average', - metavar = 'string', - help = 'name of the group in "DataContainers" containing grain average data. '\ - + 'Leave empty for pointwise data') -parser.add_option('--phase', - dest = 'phase', - type = 'string', - metavar = 'string', - help = 'name of the dataset containing pointwise/average phase IDs [%default]') -parser.add_option('--microstructure', - dest = 'microstructure', - type = 'string', - metavar = 'string', - help = 'name of the dataset connecting pointwise and average data [%default]') -parser.add_option('-q', '--quaternion', - dest = 'quaternion', - type = 'string', - metavar='string', - help = 'name of the dataset containing pointwise/average orientation as quaternion [%default]') - -parser.set_defaults(pointwise = 'CellData', - quaternion = 'Quats', - phase = 'Phases', - microstructure = 'FeatureIds', - ) - -(options, filenames) = parser.parse_args() - -if options.basegroup is None: - parser.error('No base group selected') - -if filenames == []: parser.error('no input file specified.') - -for name in filenames: - damask.util.report(scriptName,name) - - geom = damask.Grid.load_DREAM3D(name,'FeatureIds') - damask.util.croak(geom) - - geom.save_ASCII(os.path.splitext(name)[0]+'.geom') diff --git a/processing/pre/geom_fromOsteonGeometry.py b/processing/pre/geom_fromOsteonGeometry.py deleted file mode 100755 index 0bdf8aa7e..000000000 --- a/processing/pre/geom_fromOsteonGeometry.py +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -from optparse import OptionParser - -import numpy as np - -import damask - - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - - -# -------------------------------------------------------------------- -# MAIN -# -------------------------------------------------------------------- - -parser = OptionParser(usage='%prog options [geomfile]', description = """ -Generate description of an osteon enclosing the Harvesian canal and separated by interstitial tissue. -The osteon phase is lamellar with a twisted plywood structure. -Its fiber orientation is oscillating by +/- amplitude within one period. - -""", version = scriptID) - - -parser.add_option('-g', '--grid', - dest='grid', type='int', - nargs=2, metavar = 'int int', - help='a,b grid of hexahedral box [%default]') -parser.add_option('-s', '--size', - dest='size', - type='float', nargs=2, metavar = 'float float', - help='x,y size of hexahedral box [%default]') -parser.add_option('-c', '--canal', - dest='canal', - type='float', metavar = 'float', - help='Haversian canal radius [%default]') -parser.add_option('-o', '--osteon', - dest='osteon', - type='float', metavar = 'float', - help='horizontal osteon radius [%default]') -parser.add_option('-l', '--lamella', - dest='period', - type='float', metavar = 'float', - help='lamella width [%default]') -parser.add_option('-a', '--amplitude', - dest='amplitude', - type='float', metavar = 'float', - help='amplitude of twisted plywood wiggle in deg [%default]') -parser.add_option( '--aspect', - dest='aspect', - type='float', metavar = 'float', - help='vertical/horizontal osteon aspect ratio [%default]') -parser.add_option('-w', '--omega', - dest='omega', - type='float', metavar = 'float', - help='rotation angle around normal of osteon [%default]') - -parser.set_defaults(canal = 25e-6, - osteon = 100e-6, - aspect = 1.0, - omega = 0.0, - period = 5e-6, - amplitude = 60, - size = (300e-6,300e-6), - grid = (512,512), - ) - -(options,filename) = parser.parse_args() - - -name = None if filename == [] else filename[0] -damask.util.report(scriptName,name) - -omega = np.deg2rad(options.omega) -rotation = np.array([[ np.cos(omega),np.sin(omega),], - [-np.sin(omega),np.cos(omega),]]) - -grid = np.array(options.grid,'i') -size = np.array(options.size,'d') - -X0,Y0 = np.meshgrid(size[0]/grid[0] * (np.arange(grid[0]) - grid[0]/2 + 0.5), - size[1]/grid[0] * (np.arange(grid[1]) - grid[1]/2 + 0.5), indexing='ij') - -X = X0*rotation[0,0] + Y0*rotation[0,1] # rotate by omega -Y = X0*rotation[1,0] + Y0*rotation[1,1] # rotate by omega - -radius = np.sqrt(X*X + Y*Y/options.aspect**2.0) -alpha = np.degrees(np.arctan2(Y/options.aspect,X)) -beta = options.amplitude*np.sin(2.0*np.pi*(radius-options.canal)/options.period) - -microstructure = np.where(radius < float(options.canal), 1,0) \ - + np.where(radius > float(options.osteon),2,0) - -# extend to 3D -size = np.append(size,np.min(size/grid)) -grid = np.append(grid,1) -microstructure = microstructure.reshape(microstructure.shape+(1,)) - -Alpha = np.zeros(grid[0]*grid[1],'d') -Beta = np.zeros(grid[0]*grid[1],'d') - -i = 3 -for y in range(grid[1]): - for x in range(grid[0]): - if microstructure[x,y] == 0: - microstructure[x,y] = i - Alpha[i] = alpha[x,y] - Beta [i] = beta [x,y] - i+=1 - -config_header = ['', - '[canal]', - '[interstitial]' - ] -for i in range(3,np.max(microstructure)): - config_header += ['[Point{}]'.format(i-2), - '(gauss)\tphi1 {:.2f}\tPhi {:.2f}\tphi2 0'.format(Alpha[i],Beta[i]) - ] - -config_header = ['', - '[canal]', - '(constituent)\tphase 1\ttexture 1\tfraction 1.0', - '[interstitial]', - '(constituent)\tphase 2\ttexture 2\tfraction 1.0' - ] -for i in range(3,np.max(microstructure)): - config_header += ['[Point{}]'.format(i-2), - '(constituent)\tphase 3\ttexture {}\tfraction 1.0'.format(i) - ] - -header = [scriptID + ' ' + ' '.join(sys.argv[1:])]\ - + config_header -geom = damask.Grid(microstructure.reshape(grid), - size,-size/2, - comments=header) -damask.util.croak(geom) - -geom.save_ASCII(sys.stdout if name is None else name) diff --git a/processing/pre/seeds_fromPokes.py b/processing/pre/seeds_fromPokes.py deleted file mode 100755 index e6eee809a..000000000 --- a/processing/pre/seeds_fromPokes.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -from io import StringIO -from optparse import OptionParser - -import numpy as np - -import damask - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - -# -------------------------------------------------------------------- -# MAIN -# -------------------------------------------------------------------- - -parser = OptionParser(usage='%prog options [file[s]]', description = """ -Create seeds file by poking at 45 degree through given geom file. -Mimics APS Beamline 34-ID-E DAXM poking. - -""", version = scriptID) - -parser.add_option('-N', '--points', - dest = 'N', - type = 'int', metavar = 'int', - help = 'number of poking locations [%default]') -parser.add_option('-b', '--box', - dest = 'box', - type = 'float', nargs = 6, metavar = ' '.join(['float']*6), - help = 'bounding box as fraction in x, y, and z directions') -parser.add_option('-x', - action = 'store_true', - dest = 'x', - help = 'poke 45 deg along x') -parser.add_option('-y', - action = 'store_true', - dest = 'y', - help = 'poke 45 deg along y') - -parser.set_defaults(x = False, - y = False, - box = [0.0,1.0,0.0,1.0,0.0,1.0], - N = 16, - ) - -(options,filenames) = parser.parse_args() -if filenames == []: filenames = [None] - -options.box = np.array(options.box).reshape(3,2) - -for name in filenames: - damask.util.report(scriptName,name) - geom = damask.Grid.load_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name) - - offset =(np.amin(options.box, axis=1)*geom.cells/geom.size).astype(int) - box = np.amax(options.box, axis=1) \ - - np.amin(options.box, axis=1) - - Nx = int(options.N/np.sqrt(options.N*geom.size[1]*box[1]/geom.size[0]/box[0])) - Ny = int(options.N/np.sqrt(options.N*geom.size[0]*box[0]/geom.size[1]/box[1])) - Nz = int(box[2]*geom.cells[2]) - - damask.util.croak('poking {} x {} x {} in box {} {} {}...'.format(Nx,Ny,Nz,*box)) - - seeds = np.zeros((Nx*Ny*Nz,4)) - g = np.zeros(3,dtype=np.int) - - n = 0 - for i in range(Nx): - for j in range(Ny): - g[0] = round((i+0.5)*box[0]*geom.cells[0]/Nx-0.5)+offset[0] - g[1] = round((j+0.5)*box[1]*geom.cells[1]/Ny-0.5)+offset[1] - for k in range(Nz): - g[2] = k + offset[2] - g %= geom.cells - seeds[n,0:3] = (g+0.5)/geom.cells # normalize coordinates to box - seeds[n, 3] = geom.material[g[0],g[1],g[2]] - if options.x: g[0] += 1 - if options.y: g[1] += 1 - n += 1 - - - comments = geom.comments \ - + [scriptID + ' ' + ' '.join(sys.argv[1:]), - 'poking\ta {}\tb {}\tc {}'.format(Nx,Ny,Nz), - 'grid\ta {}\tb {}\tc {}'.format(*geom.cells), - 'size\tx {}\ty {}\tz {}'.format(*geom.size), - 'origin\tx {}\ty {}\tz {}'.format(*geom.origin), - ] - - table = damask.Table(seeds,{'pos':(3,),'material':(1,)},comments) - table.set('material',table.get('material').astype(np.int))\ - .save(sys.stdout if name is None else \ - os.path.splitext(name)[0]+f'_poked_{options.N}.seeds',legacy=True) From 3e8bcd322595550ccd353fbcef65269f2ff9d2e0 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 09:19:59 +0100 Subject: [PATCH 015/219] cleaning examples, using consistent names - examples in repository should only show the most basic steps - MSC.Marc, marc => Marc --- PRIVATE | 2 +- examples/{MSC.Marc => Marc}/material.config | 0 examples/{MSC.Marc => Marc}/rotation.mud | Bin .../EshelbyInclusion/config/elastic_Ti.config | 7 - .../config/elastic_fullyAnisotropic.config | 11 - .../config/elastic_isotropic.config | 4 - .../EshelbyInclusion/config/thermal.config | 3 - .../config/thermalExpansion_Ti.config | 8 - .../thermalExpansion_fullyAnisotropic.config | 9 - .../config/thermalExpansion_isotropic.config | 6 - .../EshelbyInclusion/geom/Ti_Ti.geom | 427 ------------------ .../geom/isotropic_anisotropic.geom | 427 ------------------ .../geom/isotropic_isotropic.geom | 427 ------------------ .../geom/isotropic_rotated.geom | 427 ------------------ .../EshelbyInclusion/material.config | 122 ----- .../EshelbyInclusion/numerics.config | 5 - .../EshelbyInclusion/thermal.load | 1 - .../Homogenization_Damage_NonLocal.config | 0 .../Homogenization_Isostrain_Parallel3.config | 0 .../Homogenization_Isostrain_SX.config | 0 .../Homogenization_Isostrain_Taylor2.config | 0 .../Homogenization_None_Dummy.config | 0 .../Homogenization_RGC_8Grains.config | 0 .../Homogenization_Thermal_Conduction.config | 0 .../Kinematics_Thermal_Expansion.config | 0 .../Phase_Damage.config | 0 .../Phase_DisloUCLA_Tungsten.config | 0 .../Phase_Dislotwin_TWIP-Steel-FeMnC.yaml | 0 .../Phase_Dislotwin_Tungsten.yaml | 0 .../Phase_Isotropic_AluminumIsotropic.yaml | 0 .../Phase_Isotropic_FreeSurface.yaml | 0 ...se_None_IsotropicVolumePreservation.config | 0 .../Phase_None_Orthorhombic.config | 0 .../Phase_Nonlocal_Aluminum.config | 0 .../Phase_Nonlocal_Nickel.config | 0 .../Phase_Phenopowerlaw_Aluminum.yaml | 0 .../Phase_Phenopowerlaw_BCC-Ferrite.yaml | 0 .../Phase_Phenopowerlaw_BCC-Martensite.yaml | 0 .../Phase_Phenopowerlaw_Gold.yaml | 0 .../Phase_Phenopowerlaw_Magnesium.yaml | 0 .../Phase_Phenopowerlaw_cpTi.yaml | 0 .../Phase_Thermal.config | 0 .../Source_Damage_IsoBrittle.config | 0 .../Source_Thermal_Dissipation.config | 0 .../{ConfigFiles => configuration}/debug.yaml | 0 .../numerics.yaml | 0 python/damask/solver/_marc.py | 2 +- src/{DAMASK_marc.f90 => DAMASK_Marc.f90} | 0 48 files changed, 2 insertions(+), 1886 deletions(-) rename examples/{MSC.Marc => Marc}/material.config (100%) rename examples/{MSC.Marc => Marc}/rotation.mud (100%) delete mode 100644 examples/SpectralMethod/EshelbyInclusion/config/elastic_Ti.config delete mode 100644 examples/SpectralMethod/EshelbyInclusion/config/elastic_fullyAnisotropic.config delete mode 100644 examples/SpectralMethod/EshelbyInclusion/config/elastic_isotropic.config delete mode 100644 examples/SpectralMethod/EshelbyInclusion/config/thermal.config delete mode 100644 examples/SpectralMethod/EshelbyInclusion/config/thermalExpansion_Ti.config delete mode 100644 examples/SpectralMethod/EshelbyInclusion/config/thermalExpansion_fullyAnisotropic.config delete mode 100644 examples/SpectralMethod/EshelbyInclusion/config/thermalExpansion_isotropic.config delete mode 100644 examples/SpectralMethod/EshelbyInclusion/geom/Ti_Ti.geom delete mode 100644 examples/SpectralMethod/EshelbyInclusion/geom/isotropic_anisotropic.geom delete mode 100644 examples/SpectralMethod/EshelbyInclusion/geom/isotropic_isotropic.geom delete mode 100644 examples/SpectralMethod/EshelbyInclusion/geom/isotropic_rotated.geom delete mode 100644 examples/SpectralMethod/EshelbyInclusion/material.config delete mode 100644 examples/SpectralMethod/EshelbyInclusion/numerics.config delete mode 100644 examples/SpectralMethod/EshelbyInclusion/thermal.load rename examples/{ConfigFiles => configuration}/Homogenization_Damage_NonLocal.config (100%) rename examples/{ConfigFiles => configuration}/Homogenization_Isostrain_Parallel3.config (100%) rename examples/{ConfigFiles => configuration}/Homogenization_Isostrain_SX.config (100%) rename examples/{ConfigFiles => configuration}/Homogenization_Isostrain_Taylor2.config (100%) rename examples/{ConfigFiles => configuration}/Homogenization_None_Dummy.config (100%) rename examples/{ConfigFiles => configuration}/Homogenization_RGC_8Grains.config (100%) rename examples/{ConfigFiles => configuration}/Homogenization_Thermal_Conduction.config (100%) rename examples/{ConfigFiles => configuration}/Kinematics_Thermal_Expansion.config (100%) rename examples/{ConfigFiles => configuration}/Phase_Damage.config (100%) rename examples/{ConfigFiles => configuration}/Phase_DisloUCLA_Tungsten.config (100%) rename examples/{ConfigFiles => configuration}/Phase_Dislotwin_TWIP-Steel-FeMnC.yaml (100%) rename examples/{ConfigFiles => configuration}/Phase_Dislotwin_Tungsten.yaml (100%) rename examples/{ConfigFiles => configuration}/Phase_Isotropic_AluminumIsotropic.yaml (100%) rename examples/{ConfigFiles => configuration}/Phase_Isotropic_FreeSurface.yaml (100%) rename examples/{ConfigFiles => configuration}/Phase_None_IsotropicVolumePreservation.config (100%) rename examples/{ConfigFiles => configuration}/Phase_None_Orthorhombic.config (100%) rename examples/{ConfigFiles => configuration}/Phase_Nonlocal_Aluminum.config (100%) rename examples/{ConfigFiles => configuration}/Phase_Nonlocal_Nickel.config (100%) rename examples/{ConfigFiles => configuration}/Phase_Phenopowerlaw_Aluminum.yaml (100%) rename examples/{ConfigFiles => configuration}/Phase_Phenopowerlaw_BCC-Ferrite.yaml (100%) rename examples/{ConfigFiles => configuration}/Phase_Phenopowerlaw_BCC-Martensite.yaml (100%) rename examples/{ConfigFiles => configuration}/Phase_Phenopowerlaw_Gold.yaml (100%) rename examples/{ConfigFiles => configuration}/Phase_Phenopowerlaw_Magnesium.yaml (100%) rename examples/{ConfigFiles => configuration}/Phase_Phenopowerlaw_cpTi.yaml (100%) rename examples/{ConfigFiles => configuration}/Phase_Thermal.config (100%) rename examples/{ConfigFiles => configuration}/Source_Damage_IsoBrittle.config (100%) rename examples/{ConfigFiles => configuration}/Source_Thermal_Dissipation.config (100%) rename examples/{ConfigFiles => configuration}/debug.yaml (100%) rename examples/{ConfigFiles => configuration}/numerics.yaml (100%) rename src/{DAMASK_marc.f90 => DAMASK_Marc.f90} (100%) diff --git a/PRIVATE b/PRIVATE index 6abcd3dba..65c7fc8fa 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 6abcd3dba91f37c747eae04c6695949e819ec54b +Subproject commit 65c7fc8fa91a65c5bc4d164b4417e4c60aac3e76 diff --git a/examples/MSC.Marc/material.config b/examples/Marc/material.config similarity index 100% rename from examples/MSC.Marc/material.config rename to examples/Marc/material.config diff --git a/examples/MSC.Marc/rotation.mud b/examples/Marc/rotation.mud similarity index 100% rename from examples/MSC.Marc/rotation.mud rename to examples/Marc/rotation.mud diff --git a/examples/SpectralMethod/EshelbyInclusion/config/elastic_Ti.config b/examples/SpectralMethod/EshelbyInclusion/config/elastic_Ti.config deleted file mode 100644 index b103eb112..000000000 --- a/examples/SpectralMethod/EshelbyInclusion/config/elastic_Ti.config +++ /dev/null @@ -1,7 +0,0 @@ -elasticity hooke - -c11 160.0e9 -c12 90.0e9 -c13 66.0e9 -c33 181.7e9 -c44 46.5e9 diff --git a/examples/SpectralMethod/EshelbyInclusion/config/elastic_fullyAnisotropic.config b/examples/SpectralMethod/EshelbyInclusion/config/elastic_fullyAnisotropic.config deleted file mode 100644 index 700a37dbd..000000000 --- a/examples/SpectralMethod/EshelbyInclusion/config/elastic_fullyAnisotropic.config +++ /dev/null @@ -1,11 +0,0 @@ -elasticity hooke - -c11 100.0e9 -c22 100.0e9 -c33 100.0e9 -c12 0.0e9 -c13 0.0e9 -c23 0.0e9 -c44 50.0e9 -c55 50.0e9 -c66 50.0e9 diff --git a/examples/SpectralMethod/EshelbyInclusion/config/elastic_isotropic.config b/examples/SpectralMethod/EshelbyInclusion/config/elastic_isotropic.config deleted file mode 100644 index 7574e9301..000000000 --- a/examples/SpectralMethod/EshelbyInclusion/config/elastic_isotropic.config +++ /dev/null @@ -1,4 +0,0 @@ -elasticity hooke - -c11 100.0e9 -c12 0.0e9 diff --git a/examples/SpectralMethod/EshelbyInclusion/config/thermal.config b/examples/SpectralMethod/EshelbyInclusion/config/thermal.config deleted file mode 100644 index 50e50f3b3..000000000 --- a/examples/SpectralMethod/EshelbyInclusion/config/thermal.config +++ /dev/null @@ -1,3 +0,0 @@ -reference_temperature 300.0 -specific_heat 1 -mass_density 1 diff --git a/examples/SpectralMethod/EshelbyInclusion/config/thermalExpansion_Ti.config b/examples/SpectralMethod/EshelbyInclusion/config/thermalExpansion_Ti.config deleted file mode 100644 index 5457be845..000000000 --- a/examples/SpectralMethod/EshelbyInclusion/config/thermalExpansion_Ti.config +++ /dev/null @@ -1,8 +0,0 @@ -(kinematics) thermal_expansion -thermal_expansion11 9.5e-6 -thermal_expansion22 9.5e-6 -thermal_expansion33 5.6e-6 - -(source) thermal_externalheat -externalheat_time 0 500 500.001 1000 # 500 secs supplying 1 Watt, then removing 1 Watt -externalheat_rate 1 1 -1 -1 diff --git a/examples/SpectralMethod/EshelbyInclusion/config/thermalExpansion_fullyAnisotropic.config b/examples/SpectralMethod/EshelbyInclusion/config/thermalExpansion_fullyAnisotropic.config deleted file mode 100644 index 7190656d3..000000000 --- a/examples/SpectralMethod/EshelbyInclusion/config/thermalExpansion_fullyAnisotropic.config +++ /dev/null @@ -1,9 +0,0 @@ -(kinematics) thermal_expansion -thermal_expansion11 5e-6 -thermal_expansion22 10e-6 -thermal_expansion33 20e-6 -lattice_structure orthorhombic - -(source) thermal_externalheat -externalheat_time 0 500 500.001 1000 # 500 secs supplying 1 Watt, then removing 1 Watt -externalheat_rate 1 1 -1 -1 diff --git a/examples/SpectralMethod/EshelbyInclusion/config/thermalExpansion_isotropic.config b/examples/SpectralMethod/EshelbyInclusion/config/thermalExpansion_isotropic.config deleted file mode 100644 index 5d039bec9..000000000 --- a/examples/SpectralMethod/EshelbyInclusion/config/thermalExpansion_isotropic.config +++ /dev/null @@ -1,6 +0,0 @@ -(kinematics) thermal_expansion -thermal_expansion11 10e-6 - -(source) thermal_externalheat -externalheat_time 0 500 500.001 1000 # 500 secs supplying 1 Watt, then removing 1 Watt -externalheat_rate 1 1 -1 -1 diff --git a/examples/SpectralMethod/EshelbyInclusion/geom/Ti_Ti.geom b/examples/SpectralMethod/EshelbyInclusion/geom/Ti_Ti.geom deleted file mode 100644 index 28b49f368..000000000 --- a/examples/SpectralMethod/EshelbyInclusion/geom/Ti_Ti.geom +++ /dev/null @@ -1,427 +0,0 @@ -9 header -geom_addPrimitive v2.0.1-1073-gc544fa1 -c 32 32 32 -d -16 -16 -16 inclusion.geom -geom_canvas v2.0.1-1073-gc544fa1 -o 16 16 16 -g 32 32 32 -geom_translate v2.0.1-1073-gc544fa1 -s 1,2,2,6 Ti_Ti.geom -geom_pack v2.0.1-1073-gc544fa1 Ti_Ti.geom isotropic_anisotropic.geom isotropic_isotropic.geom isotropic_rotated.geom -grid a 32 b 32 c 32 -size x 0.5 y 0.5 z 0.5 -origin x 0.25 y 0.25 z 0.25 -homogenization 1 -microstructures 2 -8623 of 2 -2 of 6 -29 of 2 -4 of 6 -27 of 2 -6 of 6 -26 of 2 -6 of 6 -27 of 2 -4 of 6 -29 of 2 -2 of 6 -798 of 2 -2 of 6 -28 of 2 -6 of 6 -25 of 2 -8 of 6 -24 of 2 -8 of 6 -23 of 2 -10 of 6 -22 of 2 -10 of 6 -23 of 2 -8 of 6 -24 of 2 -8 of 6 -25 of 2 -6 of 6 -28 of 2 -2 of 6 -701 of 2 -4 of 6 -26 of 2 -8 of 6 -23 of 2 -10 of 6 -22 of 2 -10 of 6 -21 of 2 -12 of 6 -20 of 2 -12 of 6 -20 of 2 -12 of 6 -20 of 2 -12 of 6 -21 of 2 -10 of 6 -22 of 2 -10 of 6 -23 of 2 -8 of 6 -26 of 2 -4 of 6 -637 of 2 -2 of 6 -27 of 2 -8 of 6 -23 of 2 -10 of 6 -21 of 2 -12 of 6 -20 of 2 -12 of 6 -20 of 2 -12 of 6 -19 of 2 -14 of 6 -18 of 2 -14 of 6 -19 of 2 -12 of 6 -20 of 2 -12 of 6 -20 of 2 -12 of 6 -21 of 2 -10 of 6 -23 of 2 -8 of 6 -27 of 2 -2 of 6 -604 of 2 -6 of 6 -24 of 2 -10 of 6 -21 of 2 -12 of 6 -20 of 2 -12 of 6 -19 of 2 -14 of 6 -18 of 2 -14 of 6 -18 of 2 -14 of 6 -18 of 2 -14 of 6 -18 of 2 -14 of 6 -18 of 2 -14 of 6 -19 of 2 -12 of 6 -20 of 2 -12 of 6 -21 of 2 -10 of 6 -24 of 2 -6 of 6 -572 of 2 -2 of 6 -27 of 2 -8 of 6 -23 of 2 -10 of 6 -21 of 2 -12 of 6 -19 of 2 -14 of 6 -18 of 2 -14 of 6 -18 of 2 -14 of 6 -17 of 2 -16 of 6 -16 of 2 -16 of 6 -17 of 2 -14 of 6 -18 of 2 -14 of 6 -18 of 2 -14 of 6 -19 of 2 -12 of 6 -21 of 2 -10 of 6 -23 of 2 -8 of 6 -27 of 2 -2 of 6 -541 of 2 -4 of 6 -26 of 2 -8 of 6 -22 of 2 -12 of 6 -20 of 2 -12 of 6 -19 of 2 -14 of 6 -18 of 2 -14 of 6 -17 of 2 -16 of 6 -16 of 2 -16 of 6 -16 of 2 -16 of 6 -16 of 2 -16 of 6 -17 of 2 -14 of 6 -18 of 2 -14 of 6 -19 of 2 -12 of 6 -20 of 2 -12 of 6 -22 of 2 -8 of 6 -26 of 2 -4 of 6 -539 of 2 -6 of 6 -24 of 2 -10 of 6 -21 of 2 -12 of 6 -19 of 2 -14 of 6 -18 of 2 -14 of 6 -17 of 2 -16 of 6 -16 of 2 -16 of 6 -16 of 2 -16 of 6 -16 of 2 -16 of 6 -16 of 2 -16 of 6 -16 of 2 -16 of 6 -17 of 2 -14 of 6 -18 of 2 -14 of 6 -19 of 2 -12 of 6 -21 of 2 -10 of 6 -24 of 2 -6 of 6 -538 of 2 -6 of 6 -24 of 2 -10 of 6 -21 of 2 -12 of 6 -19 of 2 -14 of 6 -18 of 2 -14 of 6 -17 of 2 -16 of 6 -16 of 2 -16 of 6 -16 of 2 -16 of 6 -16 of 2 -16 of 6 -16 of 2 -16 of 6 -16 of 2 -16 of 6 -17 of 2 -14 of 6 -18 of 2 -14 of 6 -19 of 2 -12 of 6 -21 of 2 -10 of 6 -24 of 2 -6 of 6 -539 of 2 -4 of 6 -26 of 2 -8 of 6 -22 of 2 -12 of 6 -20 of 2 -12 of 6 -19 of 2 -14 of 6 -18 of 2 -14 of 6 -17 of 2 -16 of 6 -16 of 2 -16 of 6 -16 of 2 -16 of 6 -16 of 2 -16 of 6 -17 of 2 -14 of 6 -18 of 2 -14 of 6 -19 of 2 -12 of 6 -20 of 2 -12 of 6 -22 of 2 -8 of 6 -26 of 2 -4 of 6 -541 of 2 -2 of 6 -27 of 2 -8 of 6 -23 of 2 -10 of 6 -21 of 2 -12 of 6 -19 of 2 -14 of 6 -18 of 2 -14 of 6 -18 of 2 -14 of 6 -17 of 2 -16 of 6 -16 of 2 -16 of 6 -17 of 2 -14 of 6 -18 of 2 -14 of 6 -18 of 2 -14 of 6 -19 of 2 -12 of 6 -21 of 2 -10 of 6 -23 of 2 -8 of 6 -27 of 2 -2 of 6 -572 of 2 -6 of 6 -24 of 2 -10 of 6 -21 of 2 -12 of 6 -20 of 2 -12 of 6 -19 of 2 -14 of 6 -18 of 2 -14 of 6 -18 of 2 -14 of 6 -18 of 2 -14 of 6 -18 of 2 -14 of 6 -18 of 2 -14 of 6 -19 of 2 -12 of 6 -20 of 2 -12 of 6 -21 of 2 -10 of 6 -24 of 2 -6 of 6 -604 of 2 -2 of 6 -27 of 2 -8 of 6 -23 of 2 -10 of 6 -21 of 2 -12 of 6 -20 of 2 -12 of 6 -20 of 2 -12 of 6 -19 of 2 -14 of 6 -18 of 2 -14 of 6 -19 of 2 -12 of 6 -20 of 2 -12 of 6 -20 of 2 -12 of 6 -21 of 2 -10 of 6 -23 of 2 -8 of 6 -27 of 2 -2 of 6 -637 of 2 -4 of 6 -26 of 2 -8 of 6 -23 of 2 -10 of 6 -22 of 2 -10 of 6 -21 of 2 -12 of 6 -20 of 2 -12 of 6 -20 of 2 -12 of 6 -20 of 2 -12 of 6 -21 of 2 -10 of 6 -22 of 2 -10 of 6 -23 of 2 -8 of 6 -26 of 2 -4 of 6 -701 of 2 -2 of 6 -28 of 2 -6 of 6 -25 of 2 -8 of 6 -24 of 2 -8 of 6 -23 of 2 -10 of 6 -22 of 2 -10 of 6 -23 of 2 -8 of 6 -24 of 2 -8 of 6 -25 of 2 -6 of 6 -28 of 2 -2 of 6 -798 of 2 -2 of 6 -29 of 2 -4 of 6 -27 of 2 -6 of 6 -26 of 2 -6 of 6 -27 of 2 -4 of 6 -29 of 2 -2 of 6 -8623 of 2 diff --git a/examples/SpectralMethod/EshelbyInclusion/geom/isotropic_anisotropic.geom b/examples/SpectralMethod/EshelbyInclusion/geom/isotropic_anisotropic.geom deleted file mode 100644 index 3d4d3eab5..000000000 --- a/examples/SpectralMethod/EshelbyInclusion/geom/isotropic_anisotropic.geom +++ /dev/null @@ -1,427 +0,0 @@ -9 header -geom_addPrimitive v2.0.1-1073-gc544fa1 -c 32 32 32 -d -16 -16 -16 inclusion.geom -geom_canvas v2.0.1-1073-gc544fa1 -o 16 16 16 -g 32 32 32 -geom_translate v2.0.1-1073-gc544fa1 -s 2,4 isotropic_anisotropic.geom -geom_pack v2.0.1-1073-gc544fa1 Ti_Ti.geom isotropic_anisotropic.geom isotropic_isotropic.geom isotropic_rotated.geom -grid a 32 b 32 c 32 -size x 0.5 y 0.5 z 0.5 -origin x 0.25 y 0.25 z 0.25 -homogenization 1 -microstructures 2 -8623 of 1 -2 of 4 -29 of 1 -4 of 4 -27 of 1 -6 of 4 -26 of 1 -6 of 4 -27 of 1 -4 of 4 -29 of 1 -2 of 4 -798 of 1 -2 of 4 -28 of 1 -6 of 4 -25 of 1 -8 of 4 -24 of 1 -8 of 4 -23 of 1 -10 of 4 -22 of 1 -10 of 4 -23 of 1 -8 of 4 -24 of 1 -8 of 4 -25 of 1 -6 of 4 -28 of 1 -2 of 4 -701 of 1 -4 of 4 -26 of 1 -8 of 4 -23 of 1 -10 of 4 -22 of 1 -10 of 4 -21 of 1 -12 of 4 -20 of 1 -12 of 4 -20 of 1 -12 of 4 -20 of 1 -12 of 4 -21 of 1 -10 of 4 -22 of 1 -10 of 4 -23 of 1 -8 of 4 -26 of 1 -4 of 4 -637 of 1 -2 of 4 -27 of 1 -8 of 4 -23 of 1 -10 of 4 -21 of 1 -12 of 4 -20 of 1 -12 of 4 -20 of 1 -12 of 4 -19 of 1 -14 of 4 -18 of 1 -14 of 4 -19 of 1 -12 of 4 -20 of 1 -12 of 4 -20 of 1 -12 of 4 -21 of 1 -10 of 4 -23 of 1 -8 of 4 -27 of 1 -2 of 4 -604 of 1 -6 of 4 -24 of 1 -10 of 4 -21 of 1 -12 of 4 -20 of 1 -12 of 4 -19 of 1 -14 of 4 -18 of 1 -14 of 4 -18 of 1 -14 of 4 -18 of 1 -14 of 4 -18 of 1 -14 of 4 -18 of 1 -14 of 4 -19 of 1 -12 of 4 -20 of 1 -12 of 4 -21 of 1 -10 of 4 -24 of 1 -6 of 4 -572 of 1 -2 of 4 -27 of 1 -8 of 4 -23 of 1 -10 of 4 -21 of 1 -12 of 4 -19 of 1 -14 of 4 -18 of 1 -14 of 4 -18 of 1 -14 of 4 -17 of 1 -16 of 4 -16 of 1 -16 of 4 -17 of 1 -14 of 4 -18 of 1 -14 of 4 -18 of 1 -14 of 4 -19 of 1 -12 of 4 -21 of 1 -10 of 4 -23 of 1 -8 of 4 -27 of 1 -2 of 4 -541 of 1 -4 of 4 -26 of 1 -8 of 4 -22 of 1 -12 of 4 -20 of 1 -12 of 4 -19 of 1 -14 of 4 -18 of 1 -14 of 4 -17 of 1 -16 of 4 -16 of 1 -16 of 4 -16 of 1 -16 of 4 -16 of 1 -16 of 4 -17 of 1 -14 of 4 -18 of 1 -14 of 4 -19 of 1 -12 of 4 -20 of 1 -12 of 4 -22 of 1 -8 of 4 -26 of 1 -4 of 4 -539 of 1 -6 of 4 -24 of 1 -10 of 4 -21 of 1 -12 of 4 -19 of 1 -14 of 4 -18 of 1 -14 of 4 -17 of 1 -16 of 4 -16 of 1 -16 of 4 -16 of 1 -16 of 4 -16 of 1 -16 of 4 -16 of 1 -16 of 4 -16 of 1 -16 of 4 -17 of 1 -14 of 4 -18 of 1 -14 of 4 -19 of 1 -12 of 4 -21 of 1 -10 of 4 -24 of 1 -6 of 4 -538 of 1 -6 of 4 -24 of 1 -10 of 4 -21 of 1 -12 of 4 -19 of 1 -14 of 4 -18 of 1 -14 of 4 -17 of 1 -16 of 4 -16 of 1 -16 of 4 -16 of 1 -16 of 4 -16 of 1 -16 of 4 -16 of 1 -16 of 4 -16 of 1 -16 of 4 -17 of 1 -14 of 4 -18 of 1 -14 of 4 -19 of 1 -12 of 4 -21 of 1 -10 of 4 -24 of 1 -6 of 4 -539 of 1 -4 of 4 -26 of 1 -8 of 4 -22 of 1 -12 of 4 -20 of 1 -12 of 4 -19 of 1 -14 of 4 -18 of 1 -14 of 4 -17 of 1 -16 of 4 -16 of 1 -16 of 4 -16 of 1 -16 of 4 -16 of 1 -16 of 4 -17 of 1 -14 of 4 -18 of 1 -14 of 4 -19 of 1 -12 of 4 -20 of 1 -12 of 4 -22 of 1 -8 of 4 -26 of 1 -4 of 4 -541 of 1 -2 of 4 -27 of 1 -8 of 4 -23 of 1 -10 of 4 -21 of 1 -12 of 4 -19 of 1 -14 of 4 -18 of 1 -14 of 4 -18 of 1 -14 of 4 -17 of 1 -16 of 4 -16 of 1 -16 of 4 -17 of 1 -14 of 4 -18 of 1 -14 of 4 -18 of 1 -14 of 4 -19 of 1 -12 of 4 -21 of 1 -10 of 4 -23 of 1 -8 of 4 -27 of 1 -2 of 4 -572 of 1 -6 of 4 -24 of 1 -10 of 4 -21 of 1 -12 of 4 -20 of 1 -12 of 4 -19 of 1 -14 of 4 -18 of 1 -14 of 4 -18 of 1 -14 of 4 -18 of 1 -14 of 4 -18 of 1 -14 of 4 -18 of 1 -14 of 4 -19 of 1 -12 of 4 -20 of 1 -12 of 4 -21 of 1 -10 of 4 -24 of 1 -6 of 4 -604 of 1 -2 of 4 -27 of 1 -8 of 4 -23 of 1 -10 of 4 -21 of 1 -12 of 4 -20 of 1 -12 of 4 -20 of 1 -12 of 4 -19 of 1 -14 of 4 -18 of 1 -14 of 4 -19 of 1 -12 of 4 -20 of 1 -12 of 4 -20 of 1 -12 of 4 -21 of 1 -10 of 4 -23 of 1 -8 of 4 -27 of 1 -2 of 4 -637 of 1 -4 of 4 -26 of 1 -8 of 4 -23 of 1 -10 of 4 -22 of 1 -10 of 4 -21 of 1 -12 of 4 -20 of 1 -12 of 4 -20 of 1 -12 of 4 -20 of 1 -12 of 4 -21 of 1 -10 of 4 -22 of 1 -10 of 4 -23 of 1 -8 of 4 -26 of 1 -4 of 4 -701 of 1 -2 of 4 -28 of 1 -6 of 4 -25 of 1 -8 of 4 -24 of 1 -8 of 4 -23 of 1 -10 of 4 -22 of 1 -10 of 4 -23 of 1 -8 of 4 -24 of 1 -8 of 4 -25 of 1 -6 of 4 -28 of 1 -2 of 4 -798 of 1 -2 of 4 -29 of 1 -4 of 4 -27 of 1 -6 of 4 -26 of 1 -6 of 4 -27 of 1 -4 of 4 -29 of 1 -2 of 4 -8623 of 1 diff --git a/examples/SpectralMethod/EshelbyInclusion/geom/isotropic_isotropic.geom b/examples/SpectralMethod/EshelbyInclusion/geom/isotropic_isotropic.geom deleted file mode 100644 index bf63f03d7..000000000 --- a/examples/SpectralMethod/EshelbyInclusion/geom/isotropic_isotropic.geom +++ /dev/null @@ -1,427 +0,0 @@ -9 header -geom_addPrimitive v2.0.1-1073-gc544fa1 -c 32 32 32 -d -16 -16 -16 inclusion.geom -geom_canvas v2.0.1-1073-gc544fa1 -o 16 16 16 -g 32 32 32 -geom_translate v2.0.1-1073-gc544fa1 -s 2,3 isotropic_isotropic.geom -geom_pack v2.0.1-1073-gc544fa1 Ti_Ti.geom isotropic_anisotropic.geom isotropic_isotropic.geom isotropic_rotated.geom -grid a 32 b 32 c 32 -size x 0.5 y 0.5 z 0.5 -origin x 0.25 y 0.25 z 0.25 -homogenization 1 -microstructures 2 -8623 of 1 -2 of 3 -29 of 1 -4 of 3 -27 of 1 -6 of 3 -26 of 1 -6 of 3 -27 of 1 -4 of 3 -29 of 1 -2 of 3 -798 of 1 -2 of 3 -28 of 1 -6 of 3 -25 of 1 -8 of 3 -24 of 1 -8 of 3 -23 of 1 -10 of 3 -22 of 1 -10 of 3 -23 of 1 -8 of 3 -24 of 1 -8 of 3 -25 of 1 -6 of 3 -28 of 1 -2 of 3 -701 of 1 -4 of 3 -26 of 1 -8 of 3 -23 of 1 -10 of 3 -22 of 1 -10 of 3 -21 of 1 -12 of 3 -20 of 1 -12 of 3 -20 of 1 -12 of 3 -20 of 1 -12 of 3 -21 of 1 -10 of 3 -22 of 1 -10 of 3 -23 of 1 -8 of 3 -26 of 1 -4 of 3 -637 of 1 -2 of 3 -27 of 1 -8 of 3 -23 of 1 -10 of 3 -21 of 1 -12 of 3 -20 of 1 -12 of 3 -20 of 1 -12 of 3 -19 of 1 -14 of 3 -18 of 1 -14 of 3 -19 of 1 -12 of 3 -20 of 1 -12 of 3 -20 of 1 -12 of 3 -21 of 1 -10 of 3 -23 of 1 -8 of 3 -27 of 1 -2 of 3 -604 of 1 -6 of 3 -24 of 1 -10 of 3 -21 of 1 -12 of 3 -20 of 1 -12 of 3 -19 of 1 -14 of 3 -18 of 1 -14 of 3 -18 of 1 -14 of 3 -18 of 1 -14 of 3 -18 of 1 -14 of 3 -18 of 1 -14 of 3 -19 of 1 -12 of 3 -20 of 1 -12 of 3 -21 of 1 -10 of 3 -24 of 1 -6 of 3 -572 of 1 -2 of 3 -27 of 1 -8 of 3 -23 of 1 -10 of 3 -21 of 1 -12 of 3 -19 of 1 -14 of 3 -18 of 1 -14 of 3 -18 of 1 -14 of 3 -17 of 1 -16 of 3 -16 of 1 -16 of 3 -17 of 1 -14 of 3 -18 of 1 -14 of 3 -18 of 1 -14 of 3 -19 of 1 -12 of 3 -21 of 1 -10 of 3 -23 of 1 -8 of 3 -27 of 1 -2 of 3 -541 of 1 -4 of 3 -26 of 1 -8 of 3 -22 of 1 -12 of 3 -20 of 1 -12 of 3 -19 of 1 -14 of 3 -18 of 1 -14 of 3 -17 of 1 -16 of 3 -16 of 1 -16 of 3 -16 of 1 -16 of 3 -16 of 1 -16 of 3 -17 of 1 -14 of 3 -18 of 1 -14 of 3 -19 of 1 -12 of 3 -20 of 1 -12 of 3 -22 of 1 -8 of 3 -26 of 1 -4 of 3 -539 of 1 -6 of 3 -24 of 1 -10 of 3 -21 of 1 -12 of 3 -19 of 1 -14 of 3 -18 of 1 -14 of 3 -17 of 1 -16 of 3 -16 of 1 -16 of 3 -16 of 1 -16 of 3 -16 of 1 -16 of 3 -16 of 1 -16 of 3 -16 of 1 -16 of 3 -17 of 1 -14 of 3 -18 of 1 -14 of 3 -19 of 1 -12 of 3 -21 of 1 -10 of 3 -24 of 1 -6 of 3 -538 of 1 -6 of 3 -24 of 1 -10 of 3 -21 of 1 -12 of 3 -19 of 1 -14 of 3 -18 of 1 -14 of 3 -17 of 1 -16 of 3 -16 of 1 -16 of 3 -16 of 1 -16 of 3 -16 of 1 -16 of 3 -16 of 1 -16 of 3 -16 of 1 -16 of 3 -17 of 1 -14 of 3 -18 of 1 -14 of 3 -19 of 1 -12 of 3 -21 of 1 -10 of 3 -24 of 1 -6 of 3 -539 of 1 -4 of 3 -26 of 1 -8 of 3 -22 of 1 -12 of 3 -20 of 1 -12 of 3 -19 of 1 -14 of 3 -18 of 1 -14 of 3 -17 of 1 -16 of 3 -16 of 1 -16 of 3 -16 of 1 -16 of 3 -16 of 1 -16 of 3 -17 of 1 -14 of 3 -18 of 1 -14 of 3 -19 of 1 -12 of 3 -20 of 1 -12 of 3 -22 of 1 -8 of 3 -26 of 1 -4 of 3 -541 of 1 -2 of 3 -27 of 1 -8 of 3 -23 of 1 -10 of 3 -21 of 1 -12 of 3 -19 of 1 -14 of 3 -18 of 1 -14 of 3 -18 of 1 -14 of 3 -17 of 1 -16 of 3 -16 of 1 -16 of 3 -17 of 1 -14 of 3 -18 of 1 -14 of 3 -18 of 1 -14 of 3 -19 of 1 -12 of 3 -21 of 1 -10 of 3 -23 of 1 -8 of 3 -27 of 1 -2 of 3 -572 of 1 -6 of 3 -24 of 1 -10 of 3 -21 of 1 -12 of 3 -20 of 1 -12 of 3 -19 of 1 -14 of 3 -18 of 1 -14 of 3 -18 of 1 -14 of 3 -18 of 1 -14 of 3 -18 of 1 -14 of 3 -18 of 1 -14 of 3 -19 of 1 -12 of 3 -20 of 1 -12 of 3 -21 of 1 -10 of 3 -24 of 1 -6 of 3 -604 of 1 -2 of 3 -27 of 1 -8 of 3 -23 of 1 -10 of 3 -21 of 1 -12 of 3 -20 of 1 -12 of 3 -20 of 1 -12 of 3 -19 of 1 -14 of 3 -18 of 1 -14 of 3 -19 of 1 -12 of 3 -20 of 1 -12 of 3 -20 of 1 -12 of 3 -21 of 1 -10 of 3 -23 of 1 -8 of 3 -27 of 1 -2 of 3 -637 of 1 -4 of 3 -26 of 1 -8 of 3 -23 of 1 -10 of 3 -22 of 1 -10 of 3 -21 of 1 -12 of 3 -20 of 1 -12 of 3 -20 of 1 -12 of 3 -20 of 1 -12 of 3 -21 of 1 -10 of 3 -22 of 1 -10 of 3 -23 of 1 -8 of 3 -26 of 1 -4 of 3 -701 of 1 -2 of 3 -28 of 1 -6 of 3 -25 of 1 -8 of 3 -24 of 1 -8 of 3 -23 of 1 -10 of 3 -22 of 1 -10 of 3 -23 of 1 -8 of 3 -24 of 1 -8 of 3 -25 of 1 -6 of 3 -28 of 1 -2 of 3 -798 of 1 -2 of 3 -29 of 1 -4 of 3 -27 of 1 -6 of 3 -26 of 1 -6 of 3 -27 of 1 -4 of 3 -29 of 1 -2 of 3 -8623 of 1 diff --git a/examples/SpectralMethod/EshelbyInclusion/geom/isotropic_rotated.geom b/examples/SpectralMethod/EshelbyInclusion/geom/isotropic_rotated.geom deleted file mode 100644 index 66f8a8f1a..000000000 --- a/examples/SpectralMethod/EshelbyInclusion/geom/isotropic_rotated.geom +++ /dev/null @@ -1,427 +0,0 @@ -9 header -geom_addPrimitive v2.0.1-1073-gc544fa1 -c 32 32 32 -d -16 -16 -16 inclusion.geom -geom_canvas v2.0.1-1073-gc544fa1 -o 16 16 16 -g 32 32 32 -geom_translate v2.0.1-1073-gc544fa1 -s 2,5 isotropic_rotated.geom -geom_pack v2.0.1-1073-gc544fa1 Ti_Ti.geom isotropic_anisotropic.geom isotropic_isotropic.geom isotropic_rotated.geom -grid a 32 b 32 c 32 -size x 0.5 y 0.5 z 0.5 -origin x 0.25 y 0.25 z 0.25 -homogenization 1 -microstructures 2 -8623 of 1 -2 of 5 -29 of 1 -4 of 5 -27 of 1 -6 of 5 -26 of 1 -6 of 5 -27 of 1 -4 of 5 -29 of 1 -2 of 5 -798 of 1 -2 of 5 -28 of 1 -6 of 5 -25 of 1 -8 of 5 -24 of 1 -8 of 5 -23 of 1 -10 of 5 -22 of 1 -10 of 5 -23 of 1 -8 of 5 -24 of 1 -8 of 5 -25 of 1 -6 of 5 -28 of 1 -2 of 5 -701 of 1 -4 of 5 -26 of 1 -8 of 5 -23 of 1 -10 of 5 -22 of 1 -10 of 5 -21 of 1 -12 of 5 -20 of 1 -12 of 5 -20 of 1 -12 of 5 -20 of 1 -12 of 5 -21 of 1 -10 of 5 -22 of 1 -10 of 5 -23 of 1 -8 of 5 -26 of 1 -4 of 5 -637 of 1 -2 of 5 -27 of 1 -8 of 5 -23 of 1 -10 of 5 -21 of 1 -12 of 5 -20 of 1 -12 of 5 -20 of 1 -12 of 5 -19 of 1 -14 of 5 -18 of 1 -14 of 5 -19 of 1 -12 of 5 -20 of 1 -12 of 5 -20 of 1 -12 of 5 -21 of 1 -10 of 5 -23 of 1 -8 of 5 -27 of 1 -2 of 5 -604 of 1 -6 of 5 -24 of 1 -10 of 5 -21 of 1 -12 of 5 -20 of 1 -12 of 5 -19 of 1 -14 of 5 -18 of 1 -14 of 5 -18 of 1 -14 of 5 -18 of 1 -14 of 5 -18 of 1 -14 of 5 -18 of 1 -14 of 5 -19 of 1 -12 of 5 -20 of 1 -12 of 5 -21 of 1 -10 of 5 -24 of 1 -6 of 5 -572 of 1 -2 of 5 -27 of 1 -8 of 5 -23 of 1 -10 of 5 -21 of 1 -12 of 5 -19 of 1 -14 of 5 -18 of 1 -14 of 5 -18 of 1 -14 of 5 -17 of 1 -16 of 5 -16 of 1 -16 of 5 -17 of 1 -14 of 5 -18 of 1 -14 of 5 -18 of 1 -14 of 5 -19 of 1 -12 of 5 -21 of 1 -10 of 5 -23 of 1 -8 of 5 -27 of 1 -2 of 5 -541 of 1 -4 of 5 -26 of 1 -8 of 5 -22 of 1 -12 of 5 -20 of 1 -12 of 5 -19 of 1 -14 of 5 -18 of 1 -14 of 5 -17 of 1 -16 of 5 -16 of 1 -16 of 5 -16 of 1 -16 of 5 -16 of 1 -16 of 5 -17 of 1 -14 of 5 -18 of 1 -14 of 5 -19 of 1 -12 of 5 -20 of 1 -12 of 5 -22 of 1 -8 of 5 -26 of 1 -4 of 5 -539 of 1 -6 of 5 -24 of 1 -10 of 5 -21 of 1 -12 of 5 -19 of 1 -14 of 5 -18 of 1 -14 of 5 -17 of 1 -16 of 5 -16 of 1 -16 of 5 -16 of 1 -16 of 5 -16 of 1 -16 of 5 -16 of 1 -16 of 5 -16 of 1 -16 of 5 -17 of 1 -14 of 5 -18 of 1 -14 of 5 -19 of 1 -12 of 5 -21 of 1 -10 of 5 -24 of 1 -6 of 5 -538 of 1 -6 of 5 -24 of 1 -10 of 5 -21 of 1 -12 of 5 -19 of 1 -14 of 5 -18 of 1 -14 of 5 -17 of 1 -16 of 5 -16 of 1 -16 of 5 -16 of 1 -16 of 5 -16 of 1 -16 of 5 -16 of 1 -16 of 5 -16 of 1 -16 of 5 -17 of 1 -14 of 5 -18 of 1 -14 of 5 -19 of 1 -12 of 5 -21 of 1 -10 of 5 -24 of 1 -6 of 5 -539 of 1 -4 of 5 -26 of 1 -8 of 5 -22 of 1 -12 of 5 -20 of 1 -12 of 5 -19 of 1 -14 of 5 -18 of 1 -14 of 5 -17 of 1 -16 of 5 -16 of 1 -16 of 5 -16 of 1 -16 of 5 -16 of 1 -16 of 5 -17 of 1 -14 of 5 -18 of 1 -14 of 5 -19 of 1 -12 of 5 -20 of 1 -12 of 5 -22 of 1 -8 of 5 -26 of 1 -4 of 5 -541 of 1 -2 of 5 -27 of 1 -8 of 5 -23 of 1 -10 of 5 -21 of 1 -12 of 5 -19 of 1 -14 of 5 -18 of 1 -14 of 5 -18 of 1 -14 of 5 -17 of 1 -16 of 5 -16 of 1 -16 of 5 -17 of 1 -14 of 5 -18 of 1 -14 of 5 -18 of 1 -14 of 5 -19 of 1 -12 of 5 -21 of 1 -10 of 5 -23 of 1 -8 of 5 -27 of 1 -2 of 5 -572 of 1 -6 of 5 -24 of 1 -10 of 5 -21 of 1 -12 of 5 -20 of 1 -12 of 5 -19 of 1 -14 of 5 -18 of 1 -14 of 5 -18 of 1 -14 of 5 -18 of 1 -14 of 5 -18 of 1 -14 of 5 -18 of 1 -14 of 5 -19 of 1 -12 of 5 -20 of 1 -12 of 5 -21 of 1 -10 of 5 -24 of 1 -6 of 5 -604 of 1 -2 of 5 -27 of 1 -8 of 5 -23 of 1 -10 of 5 -21 of 1 -12 of 5 -20 of 1 -12 of 5 -20 of 1 -12 of 5 -19 of 1 -14 of 5 -18 of 1 -14 of 5 -19 of 1 -12 of 5 -20 of 1 -12 of 5 -20 of 1 -12 of 5 -21 of 1 -10 of 5 -23 of 1 -8 of 5 -27 of 1 -2 of 5 -637 of 1 -4 of 5 -26 of 1 -8 of 5 -23 of 1 -10 of 5 -22 of 1 -10 of 5 -21 of 1 -12 of 5 -20 of 1 -12 of 5 -20 of 1 -12 of 5 -20 of 1 -12 of 5 -21 of 1 -10 of 5 -22 of 1 -10 of 5 -23 of 1 -8 of 5 -26 of 1 -4 of 5 -701 of 1 -2 of 5 -28 of 1 -6 of 5 -25 of 1 -8 of 5 -24 of 1 -8 of 5 -23 of 1 -10 of 5 -22 of 1 -10 of 5 -23 of 1 -8 of 5 -24 of 1 -8 of 5 -25 of 1 -6 of 5 -28 of 1 -2 of 5 -798 of 1 -2 of 5 -29 of 1 -4 of 5 -27 of 1 -6 of 5 -26 of 1 -6 of 5 -27 of 1 -4 of 5 -29 of 1 -2 of 5 -8623 of 1 diff --git a/examples/SpectralMethod/EshelbyInclusion/material.config b/examples/SpectralMethod/EshelbyInclusion/material.config deleted file mode 100644 index cd926ba67..000000000 --- a/examples/SpectralMethod/EshelbyInclusion/material.config +++ /dev/null @@ -1,122 +0,0 @@ -#-------------------# - -#-------------------# - -[direct] -mech none - -thermal adiabatic -t0 330.0 -(output) temperature - -#-------------------# - -#-------------------# - -#................. -[isotropic matrix] - -lattice_structure iso -plasticity none -{config/elastic_isotropic.config} -{config/thermal.config} - -(output) f -(output) p -(output) fe -(output) fi -(output) fp - -#................. -[Ti matrix] - -lattice_structure hex -c/a 1.587 -plasticity none -{config/elastic_Ti.config} -{config/thermal.config} - -(output) f -(output) p -(output) fe -(output) fi -(output) fp - -#................. -[isotropic inclusion] - -lattice_structure iso -plasticity none -{config/elastic_isotropic.config} -{config/thermal.config} -{config/thermalExpansion_isotropic.config} - -(output) f -(output) p -(output) fe -(output) fi -(output) fp - -#................. -[anisotropic inclusion] - -lattice_structure orthorhombic -plasticity none -{config/elastic_fullyAnisotropic.config} -{config/thermal.config} -{config/thermalExpansion_fullyAnisotropic.config} - -(output) f -(output) p -(output) fe -(output) fi -(output) fp - -#................. -[Ti inclusion] - -lattice_structure hex -c/a 1.587 -plasticity none -{config/elastic_Ti.config} -{config/thermal.config} -{config/thermalExpansion_Ti.config} - -(output) f -(output) p -(output) fe -(output) fi -(output) fp - -#--------------------------# - -#--------------------------# - -[isotropic matrix] -(constituent) phase 1 texture 1 fraction 1.0 - -[Ti matrix] -(constituent) phase 2 texture 1 fraction 1.0 - -[isotropic inclusion] -(constituent) phase 3 texture 1 fraction 1.0 - -[anisotropic inclusion] -(constituent) phase 4 texture 1 fraction 1.0 - -[rotated inclusion] -(constituent) phase 4 texture 2 fraction 1.0 - -[Ti inclusion] -(constituent) phase 5 texture 1 fraction 1.0 - -#--------------------------# - -#--------------------------# - -[cube] -(gauss) phi1 0.0 Phi 0.0 phi2 0.0 - -[rotated] -(gauss) phi1 0.0 Phi 45.0 phi2 0.0 - diff --git a/examples/SpectralMethod/EshelbyInclusion/numerics.config b/examples/SpectralMethod/EshelbyInclusion/numerics.config deleted file mode 100644 index 191c204c8..000000000 --- a/examples/SpectralMethod/EshelbyInclusion/numerics.config +++ /dev/null @@ -1,5 +0,0 @@ -#spectralsolver polarisation -spectralderivative fwbw_difference -err_div_tolrel 1e-3 -itmin 2 -petsc_options -mech_snes_type anderson -mech_snes_anderson_beta 1.0 -mech_snes_anderson_restart 10 -thermal_snes_type anderson -thermal_snes_anderson_beta 1.0 diff --git a/examples/SpectralMethod/EshelbyInclusion/thermal.load b/examples/SpectralMethod/EshelbyInclusion/thermal.load deleted file mode 100644 index a13aaa9e3..000000000 --- a/examples/SpectralMethod/EshelbyInclusion/thermal.load +++ /dev/null @@ -1 +0,0 @@ -Fdot 0 0 0 0 0 0 0 0 0 stress * * * * * * * * * time 1000 incs 10 diff --git a/examples/ConfigFiles/Homogenization_Damage_NonLocal.config b/examples/configuration/Homogenization_Damage_NonLocal.config similarity index 100% rename from examples/ConfigFiles/Homogenization_Damage_NonLocal.config rename to examples/configuration/Homogenization_Damage_NonLocal.config diff --git a/examples/ConfigFiles/Homogenization_Isostrain_Parallel3.config b/examples/configuration/Homogenization_Isostrain_Parallel3.config similarity index 100% rename from examples/ConfigFiles/Homogenization_Isostrain_Parallel3.config rename to examples/configuration/Homogenization_Isostrain_Parallel3.config diff --git a/examples/ConfigFiles/Homogenization_Isostrain_SX.config b/examples/configuration/Homogenization_Isostrain_SX.config similarity index 100% rename from examples/ConfigFiles/Homogenization_Isostrain_SX.config rename to examples/configuration/Homogenization_Isostrain_SX.config diff --git a/examples/ConfigFiles/Homogenization_Isostrain_Taylor2.config b/examples/configuration/Homogenization_Isostrain_Taylor2.config similarity index 100% rename from examples/ConfigFiles/Homogenization_Isostrain_Taylor2.config rename to examples/configuration/Homogenization_Isostrain_Taylor2.config diff --git a/examples/ConfigFiles/Homogenization_None_Dummy.config b/examples/configuration/Homogenization_None_Dummy.config similarity index 100% rename from examples/ConfigFiles/Homogenization_None_Dummy.config rename to examples/configuration/Homogenization_None_Dummy.config diff --git a/examples/ConfigFiles/Homogenization_RGC_8Grains.config b/examples/configuration/Homogenization_RGC_8Grains.config similarity index 100% rename from examples/ConfigFiles/Homogenization_RGC_8Grains.config rename to examples/configuration/Homogenization_RGC_8Grains.config diff --git a/examples/ConfigFiles/Homogenization_Thermal_Conduction.config b/examples/configuration/Homogenization_Thermal_Conduction.config similarity index 100% rename from examples/ConfigFiles/Homogenization_Thermal_Conduction.config rename to examples/configuration/Homogenization_Thermal_Conduction.config diff --git a/examples/ConfigFiles/Kinematics_Thermal_Expansion.config b/examples/configuration/Kinematics_Thermal_Expansion.config similarity index 100% rename from examples/ConfigFiles/Kinematics_Thermal_Expansion.config rename to examples/configuration/Kinematics_Thermal_Expansion.config diff --git a/examples/ConfigFiles/Phase_Damage.config b/examples/configuration/Phase_Damage.config similarity index 100% rename from examples/ConfigFiles/Phase_Damage.config rename to examples/configuration/Phase_Damage.config diff --git a/examples/ConfigFiles/Phase_DisloUCLA_Tungsten.config b/examples/configuration/Phase_DisloUCLA_Tungsten.config similarity index 100% rename from examples/ConfigFiles/Phase_DisloUCLA_Tungsten.config rename to examples/configuration/Phase_DisloUCLA_Tungsten.config diff --git a/examples/ConfigFiles/Phase_Dislotwin_TWIP-Steel-FeMnC.yaml b/examples/configuration/Phase_Dislotwin_TWIP-Steel-FeMnC.yaml similarity index 100% rename from examples/ConfigFiles/Phase_Dislotwin_TWIP-Steel-FeMnC.yaml rename to examples/configuration/Phase_Dislotwin_TWIP-Steel-FeMnC.yaml diff --git a/examples/ConfigFiles/Phase_Dislotwin_Tungsten.yaml b/examples/configuration/Phase_Dislotwin_Tungsten.yaml similarity index 100% rename from examples/ConfigFiles/Phase_Dislotwin_Tungsten.yaml rename to examples/configuration/Phase_Dislotwin_Tungsten.yaml diff --git a/examples/ConfigFiles/Phase_Isotropic_AluminumIsotropic.yaml b/examples/configuration/Phase_Isotropic_AluminumIsotropic.yaml similarity index 100% rename from examples/ConfigFiles/Phase_Isotropic_AluminumIsotropic.yaml rename to examples/configuration/Phase_Isotropic_AluminumIsotropic.yaml diff --git a/examples/ConfigFiles/Phase_Isotropic_FreeSurface.yaml b/examples/configuration/Phase_Isotropic_FreeSurface.yaml similarity index 100% rename from examples/ConfigFiles/Phase_Isotropic_FreeSurface.yaml rename to examples/configuration/Phase_Isotropic_FreeSurface.yaml diff --git a/examples/ConfigFiles/Phase_None_IsotropicVolumePreservation.config b/examples/configuration/Phase_None_IsotropicVolumePreservation.config similarity index 100% rename from examples/ConfigFiles/Phase_None_IsotropicVolumePreservation.config rename to examples/configuration/Phase_None_IsotropicVolumePreservation.config diff --git a/examples/ConfigFiles/Phase_None_Orthorhombic.config b/examples/configuration/Phase_None_Orthorhombic.config similarity index 100% rename from examples/ConfigFiles/Phase_None_Orthorhombic.config rename to examples/configuration/Phase_None_Orthorhombic.config diff --git a/examples/ConfigFiles/Phase_Nonlocal_Aluminum.config b/examples/configuration/Phase_Nonlocal_Aluminum.config similarity index 100% rename from examples/ConfigFiles/Phase_Nonlocal_Aluminum.config rename to examples/configuration/Phase_Nonlocal_Aluminum.config diff --git a/examples/ConfigFiles/Phase_Nonlocal_Nickel.config b/examples/configuration/Phase_Nonlocal_Nickel.config similarity index 100% rename from examples/ConfigFiles/Phase_Nonlocal_Nickel.config rename to examples/configuration/Phase_Nonlocal_Nickel.config diff --git a/examples/ConfigFiles/Phase_Phenopowerlaw_Aluminum.yaml b/examples/configuration/Phase_Phenopowerlaw_Aluminum.yaml similarity index 100% rename from examples/ConfigFiles/Phase_Phenopowerlaw_Aluminum.yaml rename to examples/configuration/Phase_Phenopowerlaw_Aluminum.yaml diff --git a/examples/ConfigFiles/Phase_Phenopowerlaw_BCC-Ferrite.yaml b/examples/configuration/Phase_Phenopowerlaw_BCC-Ferrite.yaml similarity index 100% rename from examples/ConfigFiles/Phase_Phenopowerlaw_BCC-Ferrite.yaml rename to examples/configuration/Phase_Phenopowerlaw_BCC-Ferrite.yaml diff --git a/examples/ConfigFiles/Phase_Phenopowerlaw_BCC-Martensite.yaml b/examples/configuration/Phase_Phenopowerlaw_BCC-Martensite.yaml similarity index 100% rename from examples/ConfigFiles/Phase_Phenopowerlaw_BCC-Martensite.yaml rename to examples/configuration/Phase_Phenopowerlaw_BCC-Martensite.yaml diff --git a/examples/ConfigFiles/Phase_Phenopowerlaw_Gold.yaml b/examples/configuration/Phase_Phenopowerlaw_Gold.yaml similarity index 100% rename from examples/ConfigFiles/Phase_Phenopowerlaw_Gold.yaml rename to examples/configuration/Phase_Phenopowerlaw_Gold.yaml diff --git a/examples/ConfigFiles/Phase_Phenopowerlaw_Magnesium.yaml b/examples/configuration/Phase_Phenopowerlaw_Magnesium.yaml similarity index 100% rename from examples/ConfigFiles/Phase_Phenopowerlaw_Magnesium.yaml rename to examples/configuration/Phase_Phenopowerlaw_Magnesium.yaml diff --git a/examples/ConfigFiles/Phase_Phenopowerlaw_cpTi.yaml b/examples/configuration/Phase_Phenopowerlaw_cpTi.yaml similarity index 100% rename from examples/ConfigFiles/Phase_Phenopowerlaw_cpTi.yaml rename to examples/configuration/Phase_Phenopowerlaw_cpTi.yaml diff --git a/examples/ConfigFiles/Phase_Thermal.config b/examples/configuration/Phase_Thermal.config similarity index 100% rename from examples/ConfigFiles/Phase_Thermal.config rename to examples/configuration/Phase_Thermal.config diff --git a/examples/ConfigFiles/Source_Damage_IsoBrittle.config b/examples/configuration/Source_Damage_IsoBrittle.config similarity index 100% rename from examples/ConfigFiles/Source_Damage_IsoBrittle.config rename to examples/configuration/Source_Damage_IsoBrittle.config diff --git a/examples/ConfigFiles/Source_Thermal_Dissipation.config b/examples/configuration/Source_Thermal_Dissipation.config similarity index 100% rename from examples/ConfigFiles/Source_Thermal_Dissipation.config rename to examples/configuration/Source_Thermal_Dissipation.config diff --git a/examples/ConfigFiles/debug.yaml b/examples/configuration/debug.yaml similarity index 100% rename from examples/ConfigFiles/debug.yaml rename to examples/configuration/debug.yaml diff --git a/examples/ConfigFiles/numerics.yaml b/examples/configuration/numerics.yaml similarity index 100% rename from examples/ConfigFiles/numerics.yaml rename to examples/configuration/numerics.yaml diff --git a/python/damask/solver/_marc.py b/python/damask/solver/_marc.py index f6c81da9f..14e21144a 100644 --- a/python/damask/solver/_marc.py +++ b/python/damask/solver/_marc.py @@ -49,7 +49,7 @@ class Marc: optimization = '', ): - usersub = Path(os.environ['DAMASK_ROOT'])/'src/DAMASK_marc' + usersub = Path(os.environ['DAMASK_ROOT'])/'src/DAMASK_Marc' usersub = usersub.parent/(usersub.name + ('.f90' if compile else '.marc')) if not usersub.is_file(): raise FileNotFoundError(f'subroutine ({"source" if compile else "binary"}) "{usersub}" not found') diff --git a/src/DAMASK_marc.f90 b/src/DAMASK_Marc.f90 similarity index 100% rename from src/DAMASK_marc.f90 rename to src/DAMASK_Marc.f90 From 51ae66f573eb4ab4ca5f889f030a37dd4733da7f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 11:40:24 +0100 Subject: [PATCH 016/219] Marc improvements - fix for 2020 - drop support for versions using old compiler - consistent capitalization --- PRIVATE | 2 +- .../2018.1/Marc_tools/comp_damask_hmp | 53 - .../2018.1/Marc_tools/comp_damask_lmp | 53 - .../2018.1/Marc_tools/comp_damask_mp | 53 - .../2018.1/Marc_tools/comp_user.original | 41 - .../2018.1/Marc_tools/include_linux64 | 804 ---- .../Marc_tools/include_linux64.original | 774 --- .../2018.1/Marc_tools/run_damask_hmp | 4131 ---------------- .../2018.1/Marc_tools/run_damask_lmp | 4131 ---------------- .../2018.1/Marc_tools/run_damask_mp | 4131 ---------------- .../2018.1/Marc_tools/run_marc.original | 4209 ----------------- .../2018.1/Mentat_bin/edit_window | 5 - .../2018.1/Mentat_bin/edit_window.original | 18 - .../2018.1/Mentat_bin/kill1.original | 8 - .../mods_MarcMentat/2018.1/Mentat_bin/kill4 | 8 - .../mods_MarcMentat/2018.1/Mentat_bin/kill5 | 8 - .../mods_MarcMentat/2018.1/Mentat_bin/kill6 | 8 - .../2018.1/Mentat_bin/submit1.original | 186 - .../mods_MarcMentat/2018.1/Mentat_bin/submit4 | 187 - .../mods_MarcMentat/2018.1/Mentat_bin/submit5 | 187 - .../mods_MarcMentat/2018.1/Mentat_bin/submit6 | 187 - .../2018.1/Mentat_menus/job_run.ms | 2703 ----------- .../2018.1/Mentat_menus/job_run.ms.original | 2568 ---------- .../2018/Marc_tools/comp_damask_hmp | 53 - .../2018/Marc_tools/comp_damask_lmp | 53 - .../2018/Marc_tools/comp_damask_mp | 53 - .../2018/Marc_tools/comp_user.original | 41 - .../2018/Marc_tools/include_linux64 | 804 ---- .../2018/Marc_tools/include_linux64.original | 774 --- .../2018/Marc_tools/run_damask_hmp | 4131 ---------------- .../2018/Marc_tools/run_damask_lmp | 4131 ---------------- .../2018/Marc_tools/run_damask_mp | 4131 ---------------- .../2018/Marc_tools/run_marc.original | 4209 ----------------- .../2018/Mentat_bin/edit_window | 5 - .../2018/Mentat_bin/edit_window.original | 18 - .../2018/Mentat_bin/kill1.original | 8 - .../mods_MarcMentat/2018/Mentat_bin/kill4 | 8 - .../mods_MarcMentat/2018/Mentat_bin/kill5 | 8 - .../mods_MarcMentat/2018/Mentat_bin/kill6 | 8 - .../2018/Mentat_bin/submit1.original | 186 - .../mods_MarcMentat/2018/Mentat_bin/submit4 | 187 - .../mods_MarcMentat/2018/Mentat_bin/submit5 | 187 - .../mods_MarcMentat/2018/Mentat_bin/submit6 | 187 - .../2018/Mentat_menus/job_run.ms | 2697 ----------- .../2018/Mentat_menus/job_run.ms.original | 2560 ---------- .../2019.1/Marc_tools/comp_damask_hmp | 53 - .../2019.1/Marc_tools/comp_damask_lmp | 53 - .../2019.1/Marc_tools/comp_damask_mp | 53 - .../2019.1/Marc_tools/comp_user.original | 41 - .../2019.1/Marc_tools/include_linux64 | 818 ---- .../Marc_tools/include_linux64.original | 788 --- .../2019.1/Marc_tools/run_damask_hmp | 4108 ---------------- .../2019.1/Marc_tools/run_damask_lmp | 4108 ---------------- .../2019.1/Marc_tools/run_damask_mp | 4108 ---------------- .../2019.1/Marc_tools/run_marc.original | 4186 ---------------- .../2019.1/Mentat_bin/edit_window | 5 - .../2019.1/Mentat_bin/edit_window.original | 18 - .../2019.1/Mentat_bin/kill1.original | 8 - .../mods_MarcMentat/2019.1/Mentat_bin/kill4 | 8 - .../mods_MarcMentat/2019.1/Mentat_bin/kill5 | 8 - .../mods_MarcMentat/2019.1/Mentat_bin/kill6 | 8 - .../2019.1/Mentat_bin/submit1.original | 189 - .../mods_MarcMentat/2019.1/Mentat_bin/submit4 | 191 - .../mods_MarcMentat/2019.1/Mentat_bin/submit5 | 191 - .../mods_MarcMentat/2019.1/Mentat_bin/submit6 | 191 - .../2019.1/Mentat_menus/job_run.ms | 2750 ----------- .../2019.1/Mentat_menus/job_run.ms.original | 2615 ---------- .../2019/Marc_tools/comp_damask_hmp | 53 - .../2019/Marc_tools/comp_damask_lmp | 53 - .../2019/Marc_tools/comp_damask_mp | 53 - .../2019/Marc_tools/comp_user.original | 41 - .../2019/Marc_tools/include_linux64 | 816 ---- .../2019/Marc_tools/include_linux64.original | 786 --- .../2019/Marc_tools/run_damask_hmp | 4105 ---------------- .../2019/Marc_tools/run_damask_lmp | 4105 ---------------- .../2019/Marc_tools/run_damask_mp | 4105 ---------------- .../2019/Marc_tools/run_marc.original | 4183 ---------------- .../2019/Mentat_bin/edit_window | 5 - .../2019/Mentat_bin/edit_window.original | 18 - .../2019/Mentat_bin/kill1.original | 8 - .../mods_MarcMentat/2019/Mentat_bin/kill4 | 8 - .../mods_MarcMentat/2019/Mentat_bin/kill5 | 8 - .../mods_MarcMentat/2019/Mentat_bin/kill6 | 8 - .../2019/Mentat_bin/submit1.original | 189 - .../mods_MarcMentat/2019/Mentat_bin/submit4 | 191 - .../mods_MarcMentat/2019/Mentat_bin/submit5 | 191 - .../mods_MarcMentat/2019/Mentat_bin/submit6 | 191 - .../2019/Mentat_menus/job_run.ms | 2708 ----------- .../2019/Mentat_menus/job_run.ms.original | 2573 ---------- .../2020/Marc_tools/include_linux64 | 6 +- src/DAMASK_Marc.f90 | 4 +- .../discretization_Marc.f90} | 0 src/{marc => Marc}/include/concom2020 | 0 src/{marc => Marc}/include/creeps2020 | 0 src/commercialFEM_fileList.f90 | 2 +- src/marc/include/concom2018 | 427 -- src/marc/include/concom2018.1 | 427 -- src/marc/include/concom2019 | 434 -- src/marc/include/concom2019.1 | 439 -- src/marc/include/creeps2018 | 66 - src/marc/include/creeps2018.1 | 66 - src/marc/include/creeps2019 | 66 - src/marc/include/creeps2019.1 | 66 - 103 files changed, 7 insertions(+), 99786 deletions(-) delete mode 100644 installation/mods_MarcMentat/2018.1/Marc_tools/comp_damask_hmp delete mode 100644 installation/mods_MarcMentat/2018.1/Marc_tools/comp_damask_lmp delete mode 100644 installation/mods_MarcMentat/2018.1/Marc_tools/comp_damask_mp delete mode 100644 installation/mods_MarcMentat/2018.1/Marc_tools/comp_user.original delete mode 100644 installation/mods_MarcMentat/2018.1/Marc_tools/include_linux64 delete mode 100644 installation/mods_MarcMentat/2018.1/Marc_tools/include_linux64.original delete mode 100644 installation/mods_MarcMentat/2018.1/Marc_tools/run_damask_hmp delete mode 100644 installation/mods_MarcMentat/2018.1/Marc_tools/run_damask_lmp delete mode 100644 installation/mods_MarcMentat/2018.1/Marc_tools/run_damask_mp delete mode 100644 installation/mods_MarcMentat/2018.1/Marc_tools/run_marc.original delete mode 100644 installation/mods_MarcMentat/2018.1/Mentat_bin/edit_window delete mode 100644 installation/mods_MarcMentat/2018.1/Mentat_bin/edit_window.original delete mode 100644 installation/mods_MarcMentat/2018.1/Mentat_bin/kill1.original delete mode 100644 installation/mods_MarcMentat/2018.1/Mentat_bin/kill4 delete mode 100644 installation/mods_MarcMentat/2018.1/Mentat_bin/kill5 delete mode 100644 installation/mods_MarcMentat/2018.1/Mentat_bin/kill6 delete mode 100644 installation/mods_MarcMentat/2018.1/Mentat_bin/submit1.original delete mode 100644 installation/mods_MarcMentat/2018.1/Mentat_bin/submit4 delete mode 100644 installation/mods_MarcMentat/2018.1/Mentat_bin/submit5 delete mode 100644 installation/mods_MarcMentat/2018.1/Mentat_bin/submit6 delete mode 100644 installation/mods_MarcMentat/2018.1/Mentat_menus/job_run.ms delete mode 100644 installation/mods_MarcMentat/2018.1/Mentat_menus/job_run.ms.original delete mode 100644 installation/mods_MarcMentat/2018/Marc_tools/comp_damask_hmp delete mode 100644 installation/mods_MarcMentat/2018/Marc_tools/comp_damask_lmp delete mode 100644 installation/mods_MarcMentat/2018/Marc_tools/comp_damask_mp delete mode 100644 installation/mods_MarcMentat/2018/Marc_tools/comp_user.original delete mode 100644 installation/mods_MarcMentat/2018/Marc_tools/include_linux64 delete mode 100644 installation/mods_MarcMentat/2018/Marc_tools/include_linux64.original delete mode 100644 installation/mods_MarcMentat/2018/Marc_tools/run_damask_hmp delete mode 100644 installation/mods_MarcMentat/2018/Marc_tools/run_damask_lmp delete mode 100644 installation/mods_MarcMentat/2018/Marc_tools/run_damask_mp delete mode 100644 installation/mods_MarcMentat/2018/Marc_tools/run_marc.original delete mode 100644 installation/mods_MarcMentat/2018/Mentat_bin/edit_window delete mode 100644 installation/mods_MarcMentat/2018/Mentat_bin/edit_window.original delete mode 100644 installation/mods_MarcMentat/2018/Mentat_bin/kill1.original delete mode 100644 installation/mods_MarcMentat/2018/Mentat_bin/kill4 delete mode 100644 installation/mods_MarcMentat/2018/Mentat_bin/kill5 delete mode 100644 installation/mods_MarcMentat/2018/Mentat_bin/kill6 delete mode 100644 installation/mods_MarcMentat/2018/Mentat_bin/submit1.original delete mode 100644 installation/mods_MarcMentat/2018/Mentat_bin/submit4 delete mode 100644 installation/mods_MarcMentat/2018/Mentat_bin/submit5 delete mode 100644 installation/mods_MarcMentat/2018/Mentat_bin/submit6 delete mode 100644 installation/mods_MarcMentat/2018/Mentat_menus/job_run.ms delete mode 100644 installation/mods_MarcMentat/2018/Mentat_menus/job_run.ms.original delete mode 100644 installation/mods_MarcMentat/2019.1/Marc_tools/comp_damask_hmp delete mode 100644 installation/mods_MarcMentat/2019.1/Marc_tools/comp_damask_lmp delete mode 100644 installation/mods_MarcMentat/2019.1/Marc_tools/comp_damask_mp delete mode 100644 installation/mods_MarcMentat/2019.1/Marc_tools/comp_user.original delete mode 100644 installation/mods_MarcMentat/2019.1/Marc_tools/include_linux64 delete mode 100644 installation/mods_MarcMentat/2019.1/Marc_tools/include_linux64.original delete mode 100644 installation/mods_MarcMentat/2019.1/Marc_tools/run_damask_hmp delete mode 100644 installation/mods_MarcMentat/2019.1/Marc_tools/run_damask_lmp delete mode 100644 installation/mods_MarcMentat/2019.1/Marc_tools/run_damask_mp delete mode 100644 installation/mods_MarcMentat/2019.1/Marc_tools/run_marc.original delete mode 100644 installation/mods_MarcMentat/2019.1/Mentat_bin/edit_window delete mode 100644 installation/mods_MarcMentat/2019.1/Mentat_bin/edit_window.original delete mode 100644 installation/mods_MarcMentat/2019.1/Mentat_bin/kill1.original delete mode 100644 installation/mods_MarcMentat/2019.1/Mentat_bin/kill4 delete mode 100644 installation/mods_MarcMentat/2019.1/Mentat_bin/kill5 delete mode 100644 installation/mods_MarcMentat/2019.1/Mentat_bin/kill6 delete mode 100644 installation/mods_MarcMentat/2019.1/Mentat_bin/submit1.original delete mode 100644 installation/mods_MarcMentat/2019.1/Mentat_bin/submit4 delete mode 100644 installation/mods_MarcMentat/2019.1/Mentat_bin/submit5 delete mode 100644 installation/mods_MarcMentat/2019.1/Mentat_bin/submit6 delete mode 100644 installation/mods_MarcMentat/2019.1/Mentat_menus/job_run.ms delete mode 100644 installation/mods_MarcMentat/2019.1/Mentat_menus/job_run.ms.original delete mode 100644 installation/mods_MarcMentat/2019/Marc_tools/comp_damask_hmp delete mode 100644 installation/mods_MarcMentat/2019/Marc_tools/comp_damask_lmp delete mode 100644 installation/mods_MarcMentat/2019/Marc_tools/comp_damask_mp delete mode 100644 installation/mods_MarcMentat/2019/Marc_tools/comp_user.original delete mode 100644 installation/mods_MarcMentat/2019/Marc_tools/include_linux64 delete mode 100644 installation/mods_MarcMentat/2019/Marc_tools/include_linux64.original delete mode 100644 installation/mods_MarcMentat/2019/Marc_tools/run_damask_hmp delete mode 100644 installation/mods_MarcMentat/2019/Marc_tools/run_damask_lmp delete mode 100644 installation/mods_MarcMentat/2019/Marc_tools/run_damask_mp delete mode 100644 installation/mods_MarcMentat/2019/Marc_tools/run_marc.original delete mode 100644 installation/mods_MarcMentat/2019/Mentat_bin/edit_window delete mode 100644 installation/mods_MarcMentat/2019/Mentat_bin/edit_window.original delete mode 100644 installation/mods_MarcMentat/2019/Mentat_bin/kill1.original delete mode 100644 installation/mods_MarcMentat/2019/Mentat_bin/kill4 delete mode 100644 installation/mods_MarcMentat/2019/Mentat_bin/kill5 delete mode 100644 installation/mods_MarcMentat/2019/Mentat_bin/kill6 delete mode 100644 installation/mods_MarcMentat/2019/Mentat_bin/submit1.original delete mode 100644 installation/mods_MarcMentat/2019/Mentat_bin/submit4 delete mode 100644 installation/mods_MarcMentat/2019/Mentat_bin/submit5 delete mode 100644 installation/mods_MarcMentat/2019/Mentat_bin/submit6 delete mode 100644 installation/mods_MarcMentat/2019/Mentat_menus/job_run.ms delete mode 100644 installation/mods_MarcMentat/2019/Mentat_menus/job_run.ms.original rename src/{marc/discretization_marc.f90 => Marc/discretization_Marc.f90} (100%) rename src/{marc => Marc}/include/concom2020 (100%) rename src/{marc => Marc}/include/creeps2020 (100%) delete mode 100644 src/marc/include/concom2018 delete mode 100644 src/marc/include/concom2018.1 delete mode 100644 src/marc/include/concom2019 delete mode 100644 src/marc/include/concom2019.1 delete mode 100644 src/marc/include/creeps2018 delete mode 100644 src/marc/include/creeps2018.1 delete mode 100644 src/marc/include/creeps2019 delete mode 100644 src/marc/include/creeps2019.1 diff --git a/PRIVATE b/PRIVATE index 65c7fc8fa..0d572a227 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 65c7fc8fa91a65c5bc4d164b4417e4c60aac3e76 +Subproject commit 0d572a2277a65097be81c31db671d4d193685831 diff --git a/installation/mods_MarcMentat/2018.1/Marc_tools/comp_damask_hmp b/installation/mods_MarcMentat/2018.1/Marc_tools/comp_damask_hmp deleted file mode 100644 index 2e6f44b77..000000000 --- a/installation/mods_MarcMentat/2018.1/Marc_tools/comp_damask_hmp +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -usernoext=$user -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - -# add BLAS options for linking - BLAS="%BLAS%" - -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user on host `hostname`" -echo "program: $program" - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$usernoext.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $BLAS \ - $SYSLIBS || \ - { - echo "$0: link failed for $usernoext.o on host `hostname`" - exit 1 - } - /bin/rm $userobj - /bin/rm $DIRJOB/*.mod - /bin/rm $DIRJOB/*.smod diff --git a/installation/mods_MarcMentat/2018.1/Marc_tools/comp_damask_lmp b/installation/mods_MarcMentat/2018.1/Marc_tools/comp_damask_lmp deleted file mode 100644 index d908d68ed..000000000 --- a/installation/mods_MarcMentat/2018.1/Marc_tools/comp_damask_lmp +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -usernoext=$user -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - -# add BLAS options for linking - BLAS="%BLAS%" - -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user on host `hostname`" -echo "program: $program" - $DFORTRANLOWMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$usernoext.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $BLAS \ - $SYSLIBS || \ - { - echo "$0: link failed for $usernoext.o on host `hostname`" - exit 1 - } - /bin/rm $userobj - /bin/rm $DIRJOB/*.mod - /bin/rm $DIRJOB/*.smod diff --git a/installation/mods_MarcMentat/2018.1/Marc_tools/comp_damask_mp b/installation/mods_MarcMentat/2018.1/Marc_tools/comp_damask_mp deleted file mode 100644 index b31d84d48..000000000 --- a/installation/mods_MarcMentat/2018.1/Marc_tools/comp_damask_mp +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -usernoext=$user -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - -# add BLAS options for linking - BLAS="%BLAS%" - -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user on host `hostname`" -echo "program: $program" - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$usernoext.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $BLAS \ - $SYSLIBS || \ - { - echo "$0: link failed for $usernoext.o on host `hostname`" - exit 1 - } - /bin/rm $userobj - /bin/rm $DIRJOB/*.mod - /bin/rm $DIRJOB/*.smod diff --git a/installation/mods_MarcMentat/2018.1/Marc_tools/comp_user.original b/installation/mods_MarcMentat/2018.1/Marc_tools/comp_user.original deleted file mode 100644 index 8679bb041..000000000 --- a/installation/mods_MarcMentat/2018.1/Marc_tools/comp_user.original +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user.f on host `hostname`" -echo "program: $program" - $FORTRAN $user.f || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$user.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $SYSLIBS || \ - { - echo "$0: link failed for $user.o on host `hostname`" - exit 1 - } - /bin/rm $userobj diff --git a/installation/mods_MarcMentat/2018.1/Marc_tools/include_linux64 b/installation/mods_MarcMentat/2018.1/Marc_tools/include_linux64 deleted file mode 100644 index 8adabaff1..000000000 --- a/installation/mods_MarcMentat/2018.1/Marc_tools/include_linux64 +++ /dev/null @@ -1,804 +0,0 @@ -# -# General definitions for the Marc 2018.1 version -# -# EM64T -# -# Linux RedHat 7.1 / SuSE 11 SP4 -# -# 64 bit MPI version -# -# Intel(R) Fortran Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.2.174 Build 20170213 -# -# Intel(R) C Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.2.174 Build 20170213 -# -# To check the O/S level, type: -# uname -a -# -# Distributed parallel MPI libraries: -# 1) HP MPI 2.3 -# To check the mpi version, type: -# mpirun -version -# 2) Intel MPI 2017.1 -# To check the mpi version, type: -# mpiexec.hydra -version -# -# To check the Compiler level, type using the compiler -# installation path: -# ifort -V -# icc -V -# -# REMARKS : This file contains the definitions of variables used during -# compilation loading and use of the MARC programmes . The -# current machine type is identified by means of the variable -# MACHINE , defined below. -# -# -# MPI_ROOT: root directory in which mpi shared libraries, etc. are located -# DIRJOB : directory in which spawned jobs should look for Marc input -# MPI_ARCH: system architecture -# MPI_EPATH: path where executable resides -# -REVISION="VERSION, BUILD" -HOSTNAME=`hostname` - -# find available memory in Mbyte on the machine -# can be set explicitly -MEMLIMIT=`free -m | awk '/Mem:/ {print $2}'` - -# set _OEM_NASTRAN to 1 for MD Nastran build -# override _OEM_NASTRAN setting with MARC_MD_NASTRAN environment variable -_OEM_NASTRAN="${MARC_MD_NASTRAN:-0}" - -# uncomment the following line for an autoforge build -#AUTOFORGE=1 -AUTOFORGE=0 -export AUTOFORGE - -# integer size -if test "$MARC_INTEGER_SIZE" = "" ; then - INTEGER_PATH= -else - INTEGER_PATH=/$MARC_INTEGER_SIZE -fi - -INTELPATH="/opt/intel/compilers_and_libraries_2017/linux" - -# find the root directory of the compiler installation: -# - if ifort is found in $PATH, then the root directory is derived -# from the path to ifort -# - if ifort is not found in $PATH, the root directory is assumed -# to be $INTELPATH and the directory in which ifort is found is -# added to $PATH -FCOMPPATH=`which "$FCOMP" 2>/dev/null` -if test -n "$FCOMPPATH"; then - # derive the root directory from $FCOMPPATH - FCOMPROOT="${FCOMPPATH%/bin/intel64/$FCOMP}" - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT="${FCOMPPATH%/bin/$FCOMP}" - fi - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT= - fi -elif test -d "$INTELPATH"; then - # check for compiler in $INTELPATH - if test -d "$INTELPATH/bin/intel64" -a \ - -x "$INTELPATH/bin/intel64/$FCOMP" ; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin/intel64:$PATH" - elif test -d "$INTELPATH/bin" -a \ - -x "$INTELPATH/bin/$FCOMP"; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin:$PATH" - else - FCOMPROOT= - fi -else - FCOMPROOT= -fi - -# DAMASK uses the HDF5 compiler wrapper around the Intel compiler -H5FC="$(h5fc -shlib -show)" -HDF5_LIB=${H5FC//ifort/} -FCOMP="$H5FC -DDAMASK_HDF5" - -# AEM -if test "$MARCDLLOUTDIR" = ""; then - DLLOUTDIR="$MARC_LIB" -else - DLLOUTDIR="$MARCDLLOUTDIR" -fi - -# settings for MKL -if test "$IMKLDIR" = ""; then - MARC_MKL="$FCOMPROOT/mkl/lib/intel64" -else - MARC_MKL=$IMKLDIR/lib/intel64 -fi - -# -# settings for Metis -# -METIS="-I$METIS_SOURCE/include" -METISLIBS="$METISLIB_DIR/libmarcddm.a $METISLIB_DIR/libmarcmetis.a " - -# -# settings for MPI -# -# RCP and RSH are used for parallel network runs -# replace with similar commands like rsh if needed -RCP=/usr/bin/scp -RSH=/usr/bin/ssh -# - - -MPI_DEFAULT=intelmpi -MPI_OTHER=hpmpi - -MPITYPE=$MPI_DEFAULT - -if test $AUTOFORGE -then - if test $AUTOFORGE = 1 - then - MPITYPE=none - fi -fi - - -# overrule MPITYPE setting with environmental variable MARC_MPITYPE -if test $MARC_MPITYPE -then - MPITYPE=$MARC_MPITYPE -fi - -# always set MPITYPE to none for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - MPITYPE=none -fi - -# Edit following lines to build with GPGPU version of BCS Solver for -# NVIDIA platforms -#BCSGPUSOLVER=NONE -BCSGPUSOLVER=BCSGPU - -# Edit following lines to set the openssl library -if test "$OPENSSL" != "NONE" -then - OPENSSL_LIB="$MARC_LIB/libcrypto.a" -fi -OPENSSL_INCLUDE=-I"$MARC_OPENSSL/include/" - -# activate contact component build if flagged -AEM_DLL=0 -if test "$AEM_BUILD" = "ON" ; then - AEM_DLL=1 - LINK_MARC_DLL="-shared -fPIC" - EXT_DLL="so" - MPITYPE=none - MPI_OTHER= - BCSGPUSOLVER=NONE - MUMPSSOLVER=NONE - CASISOLVER=NONE -fi - -SOLVERFLAGS= -if test "$BCSGPUSOLVER" = BCSGPU -then - SOLVERFLAGS="$SOLVERFLAGS -DBCSGPU -DCUDA" - BCS_DIR=bcsgpusolver -else - BCS_DIR=bcssolver -fi -# -# settings for MPI -# -DDM= -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - FCOMPMPI=mpif90 - export MPI_ROOT=$MARC_HPMPI - export MPI_REMSH=$RSH - export MPI_F77=$FCOMP - ARCHITECTURE=linux_amd64 - DDM="-I$MPI_ROOT/include/64 -DDDM -DHPMPI" - MPI_CLEAN= - export MPI_EPATH=$MARC_BIN - export LD_LIBRARY_PATH=$MPI_ROOT/lib/$ARCHITECTURE:$MARC_LIB:$MARC_LIB_SHARED:$LD_LIBRARY_PATH - export MPIHPSPECIAL="-e MPI_FLAGS=E,T,y1" -# Below line is moved in run_marc file -# export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - export MPIHPSPECIAL="$MPIHPSPECIAL -e BINDIR=$MARC_BIN" - if test -n "$MSC_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e MSC_LICENSE_FILE=$MSC_LICENSE_FILE" - fi - if test -n "$LM_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LM_LICENSE_FILE=$LM_LICENSE_FILE" - fi - export MPIHPSPECIAL="$MPIHPSPECIAL -e MPI_LIC_CHECKER=$MPI_ROOT/bin/licensing/amd64_s8/lichk.x" - RUN_JOB2="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -f " - RUN_JOB1="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -w $MPIHPSPECIAL -np " - RUN_JOB0= - fi - if test $MPITYPE = intelmpi - then - INTELMPI_VERSION=HYDRA - FCOMPMPI=mpiifort - MPI_ROOT=$MARC_INTELMPI - DDM="-I${MPI_ROOT}/include -DDDM" - PATH=$MPI_ROOT/bin:$PATH - export PATH - LD_LIBRARY_PATH=$MPI_ROOT/lib:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - if test $INTELMPI_VERSION = HYDRA - then - RUN_JOB1="${MPI_ROOT}/bin/mpiexec.hydra -genvall -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec.hydra -genvall" - else - RUN_JOB1="${MPI_ROOT}/bin/mpiexec -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec -configfile " - fi - RUN_JOB0= - MPI_CLEAN= - MPI_EPATH=$MARC_BIN - MPIR_HOME=$MPI_ROOT - MPICH_F77=$FCOMP - MPICH_F77LINKER=$FCOMP - export MPI_ROOT MPI_EPATH MPIR_HOME MPICH_F77 MPICH_F77LINKER - I_MPI_PIN_DOMAIN=node - export I_MPI_PIN_DOMAIN - fi -else - MPI_ROOT=$MARC_DUMMYMPI - export MPI_ROOT=$MARC_DUMMYMPI - DDM="-I$MPI_ROOT/include" -fi - -# -# variables for the "maintain" script -# - -MACHINENAME=LINUX -MACHINE64BIT=yes -MACHINE=Linux_EM64T -DEV=/dev/tape -GETLOG="whoami" -CLEAR="clear" -MY_UNAME=`uname -a` - -# Edit following 2 lines to build with VKI Solver -#VKISOLVER=VKI -VKISOLVER=NONE - -# Edit following 2 lines to build with CASI Solver -CASISOLVER=CASI -if test "$MARC_CASISOLVER" = "NONE" ; then - CASISOLVER=NONE -fi -#CASISOLVER=NONE - -# Edit following 2 lines to build with MF2 Solver -MF2SOLVER=NONE -#MF2SOLVER=SERIAL -#MF2SOLVER=MF2PARALLEL - -# Edit following lines to build with Intel(c) Multithreaded solver (PARDISO) -#INTELSOLVER=NONE -INTELSOLVER=PARDISO - -# Edit following lines to build with MUMPS -if test "$MARC_INTEGER_SIZE" = "i4" ; then - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -else - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -fi - -# Edit following 2 lines to build MARC dynamic shared library -MARC_DLL=MARC_DLL -MARC_DLL=NONE - -# always set VKISOLVER, CASISOLVER, BCSGPUSOLVER, and MARC_DLL to NONE for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE - MARC_DLL=NONE -fi -if test "$AEM_DLL" -eq 1 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE -fi - -# -# define Fortran and C compile syntax -# -if test "$VKISOLVER" = VKI -then - SOLVERFLAGS="$SOLVERFLAGS -DVKI" -fi - -if test "$CASISOLVER" = CASI -then - SOLVERFLAGS="$SOLVERFLAGS -DCASI" -fi - -if test "$MF2SOLVER" = MF2PARALLEL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2PARALLEL" -fi -if test "$MF2SOLVER" = MF2SERIAL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2SERIAL" -fi - -if test "$INTELSOLVER" = PARDISO -then - SOLVERFLAGS="$SOLVERFLAGS -DPARDISO" -fi - -if test "$MUMPSSOLVER" = MUMPS -then - SOLVERFLAGS="$SOLVERFLAGS -DMUMPS" -fi - - -if test "$MARC_DLL" = MARC_DLL -then - SOLVERFLAGS="$SOLVERFLAGS -DMARC_DLL" -fi - -LINK_OPT= -DEBUG_OPT= -C_DEBUG_OPT= - -#Uncomment following line to build Marc in debuggable mode -MARCDEBUG= -#MARCDEBUG="ON" - -if test "$MARCDEBUG" = "ON" -then - LINK_OPT="-debug -traceback" - DEBUG_OPT="-debug -traceback" - C_DEBUG_OPT="-debug -traceback" -fi - - -MARCCHECK= -#MARCCHECK="ON" -if test "$MARCCHECK" = "ON" -then - DEBUG_OPT="$DEBUG_OPT -fpe0 -fp-stack-check -check all -ftrapuv " - C_DEBUG_OPT="$C_DEBUG_OPT -fp-stack-check -check-uninit -Wformat -ftrapuv " -fi - -MARCCODECOV= -#MARCCODECOV="ON" - -MARCCODEPROF= -#MARCCODEPROF="ON" - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - I8FFLAGS= - I8DEFINES= - I8CDEFINES= -else - I8FFLAGS="-i8 -integer-size 64" - I8DEFINES="-DI64 -DINT=8" - I8CDEFINES="-U_DOUBLE -D_SINGLE" -fi - -MTHREAD=OPENMP -if test "$MARC_OPENMP" = "NONE" ; then - MTHREAD=NONE -fi -#MTHREAD=NONE -if test "$_OEM_NASTRAN" -ne 0 -then -MTHREAD=NONE -fi -if test "$AEM_DLL" -eq 1 -then - MTHREAD=NONE - CASISOLVER=NONE - VKISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - BCSGPUSOLVER=NONE - OPENSSL_LIB= - MARC_DLL=NONE - METISLIBS= -fi - -OMP_COMPAT=NO -OMP_COMPAT=YES -if test "$MTHREAD" = "NONE" -then -OMP_COMPAT=NO -fi - -CDEFINES= -FDEFINES= - -if test "$_OEM_NASTRAN" -ne 0 -then - CDEFINES="$CDEFINES -D_OEM_NASTRAN" - FDEFINES="$FDEFINES -D_OEM_NASTRAN" -fi - -FDEFINES="$FDEFINES -D_IMPLICITNONE" - -if test "$_OEM_NASTRAN" -eq 0 -then - FDEFINES="$FDEFINES -DMKL -DOPENMP" -fi - -if test "$OMP_COMPAT" = "YES" -then - FDEFINES="$FDEFINES -DOMP_COMPAT" -fi - -# -D_MSCMARC -FDEFINES="$FDEFINES -D_MSCMARC $DEBUG_OPT $MARC_SIMUFACT" -CDEFINES="$CDEFINES -D_MSCMARC $C_DEBUG_OPT $I8CDEFINES" - -if test "$AEM_DLL" -eq 1 -then - FDEFINES="$FDEFINES -D_AEMNL -DAAA" - CDEFINES="$CDEFINES -D_AEMNL -DAAA" -fi - -CINCL="-I$MARC_SOURCE/mdsrc -I$MARC_SOURCE/csource $METIS" -if test "$_OEM_NASTRAN" -ne 0 -then - CINCL="$CINCL -I../../include" -fi - -CC_OPT= -if test "$MTHREAD" = "OPENMP" -then - CC_OPT=" $CC_OPT -qopenmp" -fi - -CC="icc -c $CC_OPT -O1 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCLOW="icc -c $CC_OPT -O0 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCHIGH="icc -c $CC_OPT -O3 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - -if test "$MARCDEBUG" = "ON" -then - CC="icc -c $CC_OPT -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCLOW="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCHIGH="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -fi - -LOAD_CC="icc $CC_OPT -O1 -DLinux -DLINUX -DLinux_intel" -CCT="$CC" -CCTLOW="$CCLOW" -CCTHIGH="$CCHIGH" - -#PROFILE="-Mprof=func" -#PROFILE="-Mprof=lines" -#PROFILE="-Mprof=func,mpi" -PROFILE= -#PROFILE="-init=snan,arrays -CB -traceback -fpe0 -fp-stack-check -check all -check uninit -ftrapuv" -if test "$MARCCODECOV" = "ON" -then -PROFILE="-prof-gen=srcpos" -fi -if test "$MARCCODEPROF" = "ON" -then -PROFILE=" $PROFILE -pg" -fi - -FORT_OPT="-c -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr -mp1 -WB -fp-model source" -if test "$MTHREAD" = "OPENMP" -then - FORT_OPT=" $FORT_OPT -qopenmp" - if test "$OMP_COMPAT" = "YES" - then - FORT_OPT=" $FORT_OPT -qopenmp-threadprivate=compat" - fi -else -# FORT_OPT=" $FORT_OPT -auto " - FORT_OPT=" $FORT_OPT -save -zero" -fi - -FORTLOW="$FCOMP $FORT_OPT $PROFILE -O0 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTRAN="$FCOMP $FORT_OPT $PROFILE -O1 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTNA="$FCOMP $FORT_OPT -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -# for compiling free form f90 files. high opt, integer(4) -FORTF90="$FCOMP -c -O3" - -# determine DAMASK version -if test -n "$DAMASK_USER"; then - DAMASKROOT=`dirname $DAMASK_USER`/.. - read DAMASKVERSION < $DAMASKROOT/VERSION - DAMASKVERSION="'"$DAMASKVERSION"'" -else - DAMASKVERSION="'N/A'" -fi - - -# DAMASK compiler calls: additional flags are in line 2 OpenMP flags in line 3 -DFORTLOWMP="$FCOMP -c -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2018.1 -DDAMASKVERSION=$DAMASKVERSION \ - -qopenmp -qopenmp-threadprivate=compat\ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -DFORTRANMP="$FCOMP -c -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2018.1 -DDAMASKVERSION=$DAMASKVERSION \ - -qopenmp -qopenmp-threadprivate=compat\ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -DFORTHIGHMP="$FCOMP -c -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2018.1 -DDAMASKVERSION=$DAMASKVERSION \ - -qopenmp -qopenmp-threadprivate=compat\ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - - -if test "$MARCDEBUG" = "ON" -then - FORTLOW="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTRAN="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTNA="$FCOMP $FORT_OPT -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -fi - - -FORTLOWT="$FORTLOW" -FORTRANT="$FORTRAN" -FORTHIGHT="$FORTHIGH" - -FORTRANMNF="$FCOMP -c $FDEFINES " -CCMNF="icc -c -O1 -DLinux -DLINUX -DLinux_intel -Dport2egcs -I$MARC_SOURCE/marctoadams/mnf/include -D_LARGEFILE64_SOURCE" - -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - LOAD="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - LOADT="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - fi -# Uncomment the following lines to turn on the tracer and commnet out the next 5 lines -# if test $MPITYPE = intelmpi -# then -# INCLUDEMPI="-I$MPI_ROOT/include -I$VT_ROOT/include" -# LOAD="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# LOADT="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# fi - if test $MPITYPE = intelmpi - then - LOAD="ifort $PROFILE $LINK_OPT -o " - LOADT="ifort $PROFILE $LINK_OPT -o " - fi -else - LOAD="$FCOMP $LINK_OPT -o " - LOADT="$FCOMP $LINK_OPT -o " -fi - -if test "$MARC_DLL" = MARC_DLL -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide -lpthread" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - -if test "$AEM_DLL" -eq 1 -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - - -XLIBS="-L/usr/X11/lib -lX11 " - -# -# define archive and ranlib syntax -# - -ARC="ar rvl" -ARD="ar dvl" -ARX="ar xl" -RAN="" - -# -# choose which libraries you want to use ( e.g. blas ) -# - -if test "$VKISOLVER" = VKI -then - VKISOLVERLIBS="$MARC_LIB/vkisolver.a" -else - VKISOLVERLIBS= -fi - -if test "$CASISOLVER" = CASI -then - CASISOLVERLIBS="$CASILIB_DIR/libmarccasi.a $CASILIB_DIR/libcasi.a" -else - CASISOLVERLIBS= -fi - -MF2SOLVERLIBS= -if test "$MF2SOLVER" = MF2PARALLEL -then - MF2SOLVERLIBS="$MARC_LIB/mf2parallel/libseq.a \ - $MARC_LIB/mf2parallel/libsym.a \ - $MARC_LIB/mf2parallel/libmet.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libnum.a \ - $MARC_LIB/mf2parallel/libutl.a \ - $MARC_LIB/mf2parallel/libr8.a \ - $MARC_LIB/mf2parallel/libz.a " -fi - -if test "$MUMPSSOLVER" = MUMPS -then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - if test $MPITYPE = none - then - MUMPSSOLVERLIBS2= - echo hello > /dev/null - fi - if test $MPITYPE = intelmpi - then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a " - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a " - fi - fi - if test $MPITYPE = hpmpi - then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a" - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a" - fi - fi -else - MUMPSSOLVERLIBS= - MUMPSSOLVERLIBS2= -fi - -if test "$BCSGPUSOLVER" = BCSGPU -then - BCSSOLVERLIBS="${BCSLIB_DIR}/bcsgpulib.a " - MARCCUDALIBS1="-L${BCSLIB_DIR}/cuda_dummy -lmarccuda " - MARCCUDALIBS2="-L${BCSLIB_DIR}/cuda -lmarccuda " - MARCCUDALIBS=$MARCCUDALIBS1 -else - BCSSOLVERLIBS="${MARC_LIB}/bcslib.a " -fi -if test "$AEM_DLL" -eq 1 -then - BCSSOLVERLIBS= -fi - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - MKLLIB="$MARC_MKL/libmkl_scalapack_lp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_lp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MARC_MKL/libmkl_blacs_intelmpi_lp64.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -else - MKLLIB="$MARC_MKL/libmkl_scalapack_ilp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_ilp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -fi - -SECLIBS="-L$MARC_LIB -llapi" - -SOLVERLIBS="${BCSSOLVERLIBS} ${VKISOLVERLIBS} ${CASISOLVERLIBS} ${MF2SOLVERLIBS} \ - $MKLLIB -L$MARC_MKL -liomp5 \ - $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/kdtree2.a $HDF5_LIB " - -SOLVERLIBS_DLL=${SOLVERLIBS} -if test "$AEM_DLL" -eq 1 -then -SOLVERLIBS_DLL="$MKLLIB -L$MARC_MKL -liomp5 $MARC_LIB/blas_src.a" -fi -MRCLIBS="$MARC_LIB/clib.a ${CASISOLVERLIBS}" -MRCLIBSPAR="$MARC_LIB/clib.a" -STUBS="$MARC_LIB/stubs.a " -MNFLIBS="$MARC_LIB/libmnf.a" -MDUSER="$MARC_LIB/md_user.a" -if test "X$MARC_SIMUFACT" != "X" -then - SFLIB="-L$SFMATDIR -lMBA_Grain $SFMATDIR/sfclib.a " -else - SFLIB=" " -fi - -OPENMP="-qopenmp" - -if test "$AEM_DLL" -eq 1 -then - LOAD_DLL=$LOAD - OPENMP= - LIBMNF= - OPENSSL=NONE -fi - -SYSLIBS=" $OPENMP -lpthread -cxxlib" - -# Uncomment the following lines to turn on the trace and comment out the next 4 lines -# if test $MPITYPE = intelmpi -# then -# SYSLIBS="-L${VT_ROOT}/lib -lVT -ldwarf -lelf -lm -lpthread \ -# -L${MPI_ROOT}/lib64 -lmpi -lmpiif -lmpigi -lrt" -# fi -if test $MPITYPE = intelmpi -then - SYSLIBS="-L${MPI_ROOT}/lib -lmpi_mt -lmpifort -lrt $OPENMP -threads -lpthread -cxxlib" -fi - - -SYSLIBSPAR=" " - -MARC_DLL_CODES="runmarc.f" - - -BLAS_SRC="dzero.f icopy.f izero.f" -if test "$_OEM_NASTRAN" -ne 0 -then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - BLAS_SRC="$BLAS_SRC dsctr.f zsctr.f dzasum.f daxpyi.f zaxpyi.f dgthr.f zgthr.f" - else - BLAS_SRC="ALL" - fi -fi - -LOW_OPT_CODES="are163.f contro.f ndext.f omarc.f omarca.f omarcb.f omarcc.f \ - omars.f fixbc.f triang.f bet049.f norst3.f eldata.f \ - elec*.f elct*.f fmeig.f oada00.f ogeig.f updtrbe2.f cycrota.f \ - cordef.f ogpk.f ogtan.f eldam.f formrbe3.f \ - inertie.f em_sso072.f cn_fol3d_qpatch6.f cosim_begin.f" -if test "$MARC_INTEGER_SIZE" = "i8" ; then - LOW_OPT_CODES="$LOW_OPT_CODES bbcseg.f" -fi - -HIGH_OPT_CODES="dpsmsa1.f dpsmsa2.f dpsmsa3.f dpsmsa4.f dpsmsa5.f dpsmsa6.f \ - dpsmsa7.f dpsmsa8.f dpsmsa9.f dpsmsa10.f dpsmsa11.f dpsmsa12.f \ - dpsmsa13.f dpsmsa14.f dpsmsa15.f dpsmsa16.f dpsmsah.f tpsmsah.f cn_qsort4_11.f " - - - -MAXNUM=1000000 diff --git a/installation/mods_MarcMentat/2018.1/Marc_tools/include_linux64.original b/installation/mods_MarcMentat/2018.1/Marc_tools/include_linux64.original deleted file mode 100644 index 749fd966e..000000000 --- a/installation/mods_MarcMentat/2018.1/Marc_tools/include_linux64.original +++ /dev/null @@ -1,774 +0,0 @@ -# -# General definitions for the Marc 2018.1 version -# -# EM64T -# -# Linux RedHat 7.1 / SuSE 11 SP4 -# -# 64 bit MPI version -# -# Intel(R) Fortran Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.2.174 Build 20170213 -# -# Intel(R) C Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.2.174 Build 20170213 -# -# To check the O/S level, type: -# uname -a -# -# Distributed parallel MPI libraries: -# 1) HP MPI 2.3 -# To check the mpi version, type: -# mpirun -version -# 2) Intel MPI 2017.1 -# To check the mpi version, type: -# mpiexec.hydra -version -# -# To check the Compiler level, type using the compiler -# installation path: -# ifort -V -# icc -V -# -# REMARKS : This file contains the definitions of variables used during -# compilation loading and use of the MARC programmes . The -# current machine type is identified by means of the variable -# MACHINE , defined below. -# -# -# MPI_ROOT: root directory in which mpi shared libraries, etc. are located -# DIRJOB : directory in which spawned jobs should look for Marc input -# MPI_ARCH: system architecture -# MPI_EPATH: path where executable resides -# -REVISION="VERSION, BUILD" -HOSTNAME=`hostname` - -# find available memory in Mbyte on the machine -# can be set explicitly -MEMLIMIT=`free -m | awk '/Mem:/ {print $2}'` - -# set _OEM_NASTRAN to 1 for MD Nastran build -# override _OEM_NASTRAN setting with MARC_MD_NASTRAN environment variable -_OEM_NASTRAN="${MARC_MD_NASTRAN:-0}" - -# uncomment the following line for an autoforge build -#AUTOFORGE=1 -AUTOFORGE=0 -export AUTOFORGE - -# integer size -if test "$MARC_INTEGER_SIZE" = "" ; then - INTEGER_PATH= -else - INTEGER_PATH=/$MARC_INTEGER_SIZE -fi - -FCOMP=ifort -INTELPATH="/opt/intel/compilers_and_libraries_2017/linux" - -# find the root directory of the compiler installation: -# - if ifort is found in $PATH, then the root directory is derived -# from the path to ifort -# - if ifort is not found in $PATH, the root directory is assumed -# to be $INTELPATH and the directory in which ifort is found is -# added to $PATH -FCOMPPATH=`which "$FCOMP" 2>/dev/null` -if test -n "$FCOMPPATH"; then - # derive the root directory from $FCOMPPATH - FCOMPROOT="${FCOMPPATH%/bin/intel64/$FCOMP}" - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT="${FCOMPPATH%/bin/$FCOMP}" - fi - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT= - fi -elif test -d "$INTELPATH"; then - # check for compiler in $INTELPATH - if test -d "$INTELPATH/bin/intel64" -a \ - -x "$INTELPATH/bin/intel64/$FCOMP" ; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin/intel64:$PATH" - elif test -d "$INTELPATH/bin" -a \ - -x "$INTELPATH/bin/$FCOMP"; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin:$PATH" - else - FCOMPROOT= - fi -else - FCOMPROOT= -fi - -# AEM -if test "$MARCDLLOUTDIR" = ""; then - DLLOUTDIR="$MARC_LIB" -else - DLLOUTDIR="$MARCDLLOUTDIR" -fi - -# settings for MKL -if test "$IMKLDIR" = ""; then - MARC_MKL="$FCOMPROOT/mkl/lib/intel64" -else - MARC_MKL=$IMKLDIR/lib/intel64 -fi - -# -# settings for Metis -# -METIS="-I$METIS_SOURCE/include" -METISLIBS="$METISLIB_DIR/libmarcddm.a $METISLIB_DIR/libmarcmetis.a " - -# -# settings for MPI -# -# RCP and RSH are used for parallel network runs -# replace with similar commands like rsh if needed -RCP=/usr/bin/scp -RSH=/usr/bin/ssh -# - - -MPI_DEFAULT=intelmpi -MPI_OTHER=hpmpi - -MPITYPE=$MPI_DEFAULT - -if test $AUTOFORGE -then - if test $AUTOFORGE = 1 - then - MPITYPE=none - fi -fi - - -# overrule MPITYPE setting with environmental variable MARC_MPITYPE -if test $MARC_MPITYPE -then - MPITYPE=$MARC_MPITYPE -fi - -# always set MPITYPE to none for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - MPITYPE=none -fi - -# Edit following lines to build with GPGPU version of BCS Solver for -# NVIDIA platforms -#BCSGPUSOLVER=NONE -BCSGPUSOLVER=BCSGPU - -# Edit following lines to set the openssl library -if test "$OPENSSL" != "NONE" -then - OPENSSL_LIB="$MARC_LIB/libcrypto.a" -fi -OPENSSL_INCLUDE=-I"$MARC_OPENSSL/include/" - -# activate contact component build if flagged -AEM_DLL=0 -if test "$AEM_BUILD" = "ON" ; then - AEM_DLL=1 - LINK_MARC_DLL="-shared -fPIC" - EXT_DLL="so" - MPITYPE=none - MPI_OTHER= - BCSGPUSOLVER=NONE - MUMPSSOLVER=NONE - CASISOLVER=NONE -fi - -SOLVERFLAGS= -if test "$BCSGPUSOLVER" = BCSGPU -then - SOLVERFLAGS="$SOLVERFLAGS -DBCSGPU -DCUDA" - BCS_DIR=bcsgpusolver -else - BCS_DIR=bcssolver -fi -# -# settings for MPI -# -DDM= -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - FCOMPMPI=mpif90 - export MPI_ROOT=$MARC_HPMPI - export MPI_REMSH=$RSH - export MPI_F77=$FCOMP - ARCHITECTURE=linux_amd64 - DDM="-I$MPI_ROOT/include/64 -DDDM -DHPMPI" - MPI_CLEAN= - export MPI_EPATH=$MARC_BIN - export LD_LIBRARY_PATH=$MPI_ROOT/lib/$ARCHITECTURE:$MARC_LIB:$MARC_LIB_SHARED:$LD_LIBRARY_PATH - export MPIHPSPECIAL="-e MPI_FLAGS=E,T,y1" -# Below line is moved in run_marc file -# export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - export MPIHPSPECIAL="$MPIHPSPECIAL -e BINDIR=$MARC_BIN" - if test -n "$MSC_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e MSC_LICENSE_FILE=$MSC_LICENSE_FILE" - fi - if test -n "$LM_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LM_LICENSE_FILE=$LM_LICENSE_FILE" - fi - export MPIHPSPECIAL="$MPIHPSPECIAL -e MPI_LIC_CHECKER=$MPI_ROOT/bin/licensing/amd64_s8/lichk.x" - RUN_JOB2="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -f " - RUN_JOB1="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -w $MPIHPSPECIAL -np " - RUN_JOB0= - fi - if test $MPITYPE = intelmpi - then - INTELMPI_VERSION=HYDRA - FCOMPMPI=mpiifort - MPI_ROOT=$MARC_INTELMPI - DDM="-I${MPI_ROOT}/include -DDDM" - PATH=$MPI_ROOT/bin:$PATH - export PATH - LD_LIBRARY_PATH=$MPI_ROOT/lib:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - if test $INTELMPI_VERSION = HYDRA - then - RUN_JOB1="${MPI_ROOT}/bin/mpiexec.hydra -genvall -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec.hydra -genvall" - else - RUN_JOB1="${MPI_ROOT}/bin/mpiexec -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec -configfile " - fi - RUN_JOB0= - MPI_CLEAN= - MPI_EPATH=$MARC_BIN - MPIR_HOME=$MPI_ROOT - MPICH_F77=$FCOMP - MPICH_F77LINKER=$FCOMP - export MPI_ROOT MPI_EPATH MPIR_HOME MPICH_F77 MPICH_F77LINKER - I_MPI_PIN_DOMAIN=node - export I_MPI_PIN_DOMAIN - fi -else - MPI_ROOT=$MARC_DUMMYMPI - export MPI_ROOT=$MARC_DUMMYMPI - DDM="-I$MPI_ROOT/include" -fi - -# -# variables for the "maintain" script -# - -MACHINENAME=LINUX -MACHINE64BIT=yes -MACHINE=Linux_EM64T -DEV=/dev/tape -GETLOG="whoami" -CLEAR="clear" -MY_UNAME=`uname -a` - -# Edit following 2 lines to build with VKI Solver -#VKISOLVER=VKI -VKISOLVER=NONE - -# Edit following 2 lines to build with CASI Solver -CASISOLVER=CASI -if test "$MARC_CASISOLVER" = "NONE" ; then - CASISOLVER=NONE -fi -#CASISOLVER=NONE - -# Edit following 2 lines to build with MF2 Solver -MF2SOLVER=NONE -#MF2SOLVER=SERIAL -#MF2SOLVER=MF2PARALLEL - -# Edit following lines to build with Intel(c) Multithreaded solver (PARDISO) -#INTELSOLVER=NONE -INTELSOLVER=PARDISO - -# Edit following lines to build with MUMPS -if test "$MARC_INTEGER_SIZE" = "i4" ; then - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -else - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -fi - -# Edit following 2 lines to build MARC dynamic shared library -MARC_DLL=MARC_DLL -MARC_DLL=NONE - -# always set VKISOLVER, CASISOLVER, BCSGPUSOLVER, and MARC_DLL to NONE for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE - MARC_DLL=NONE -fi -if test "$AEM_DLL" -eq 1 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE -fi - -# -# define Fortran and C compile syntax -# -if test "$VKISOLVER" = VKI -then - SOLVERFLAGS="$SOLVERFLAGS -DVKI" -fi - -if test "$CASISOLVER" = CASI -then - SOLVERFLAGS="$SOLVERFLAGS -DCASI" -fi - -if test "$MF2SOLVER" = MF2PARALLEL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2PARALLEL" -fi -if test "$MF2SOLVER" = MF2SERIAL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2SERIAL" -fi - -if test "$INTELSOLVER" = PARDISO -then - SOLVERFLAGS="$SOLVERFLAGS -DPARDISO" -fi - -if test "$MUMPSSOLVER" = MUMPS -then - SOLVERFLAGS="$SOLVERFLAGS -DMUMPS" -fi - - -if test "$MARC_DLL" = MARC_DLL -then - SOLVERFLAGS="$SOLVERFLAGS -DMARC_DLL" -fi - -LINK_OPT= -DEBUG_OPT= -C_DEBUG_OPT= - -#Uncomment following line to build Marc in debuggable mode -MARCDEBUG= -#MARCDEBUG="ON" - -if test "$MARCDEBUG" = "ON" -then - LINK_OPT="-debug -traceback" - DEBUG_OPT="-debug -traceback" - C_DEBUG_OPT="-debug -traceback" -fi - - -MARCCHECK= -#MARCCHECK="ON" -if test "$MARCCHECK" = "ON" -then - DEBUG_OPT="$DEBUG_OPT -fpe0 -fp-stack-check -check all -ftrapuv " - C_DEBUG_OPT="$C_DEBUG_OPT -fp-stack-check -check-uninit -Wformat -ftrapuv " -fi - -MARCCODECOV= -#MARCCODECOV="ON" - -MARCCODEPROF= -#MARCCODEPROF="ON" - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - I8FFLAGS= - I8DEFINES= - I8CDEFINES= -else - I8FFLAGS="-i8" - I8DEFINES="-DI64" - I8CDEFINES="-U_DOUBLE -D_SINGLE" -fi - -MTHREAD=OPENMP -if test "$MARC_OPENMP" = "NONE" ; then - MTHREAD=NONE -fi -#MTHREAD=NONE -if test "$_OEM_NASTRAN" -ne 0 -then -MTHREAD=NONE -fi -if test "$AEM_DLL" -eq 1 -then - MTHREAD=NONE - CASISOLVER=NONE - VKISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - BCSGPUSOLVER=NONE - OPENSSL_LIB= - MARC_DLL=NONE - METISLIBS= -fi - -OMP_COMPAT=NO -OMP_COMPAT=YES -if test "$MTHREAD" = "NONE" -then -OMP_COMPAT=NO -fi - -CDEFINES= -FDEFINES= - -if test "$_OEM_NASTRAN" -ne 0 -then - CDEFINES="$CDEFINES -D_OEM_NASTRAN" - FDEFINES="$FDEFINES -D_OEM_NASTRAN" -fi - -FDEFINES="$FDEFINES -D_IMPLICITNONE" - -if test "$_OEM_NASTRAN" -eq 0 -then - FDEFINES="$FDEFINES -DMKL -DOPENMP" -fi - -if test "$OMP_COMPAT" = "YES" -then - FDEFINES="$FDEFINES -DOMP_COMPAT" -fi - -# -D_MSCMARC -FDEFINES="$FDEFINES -D_MSCMARC $DEBUG_OPT $MARC_SIMUFACT" -CDEFINES="$CDEFINES -D_MSCMARC $C_DEBUG_OPT $I8CDEFINES" - -if test "$AEM_DLL" -eq 1 -then - FDEFINES="$FDEFINES -D_AEMNL -DAAA" - CDEFINES="$CDEFINES -D_AEMNL -DAAA" -fi - -CINCL="-I$MARC_SOURCE/mdsrc -I$MARC_SOURCE/csource $METIS" -if test "$_OEM_NASTRAN" -ne 0 -then - CINCL="$CINCL -I../../include" -fi - -CC_OPT= -if test "$MTHREAD" = "OPENMP" -then - CC_OPT=" $CC_OPT -qopenmp" -fi - -CC="icc -c $CC_OPT -O1 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCLOW="icc -c $CC_OPT -O0 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCHIGH="icc -c $CC_OPT -O3 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - -if test "$MARCDEBUG" = "ON" -then - CC="icc -c $CC_OPT -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCLOW="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCHIGH="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -fi - -LOAD_CC="icc $CC_OPT -O1 -DLinux -DLINUX -DLinux_intel" -CCT="$CC" -CCTLOW="$CCLOW" -CCTHIGH="$CCHIGH" - -#PROFILE="-Mprof=func" -#PROFILE="-Mprof=lines" -#PROFILE="-Mprof=func,mpi" -PROFILE= -#PROFILE="-init=snan,arrays -CB -traceback -fpe0 -fp-stack-check -check all -check uninit -ftrapuv" -if test "$MARCCODECOV" = "ON" -then -PROFILE="-prof-gen=srcpos" -fi -if test "$MARCCODEPROF" = "ON" -then -PROFILE=" $PROFILE -pg" -fi - -FORT_OPT="-c -assume byterecl -safe_cray_ptr -mp1 -WB -fp-model source" -if test "$MTHREAD" = "OPENMP" -then - FORT_OPT=" $FORT_OPT -qopenmp" - if test "$OMP_COMPAT" = "YES" - then - FORT_OPT=" $FORT_OPT -qopenmp-threadprivate=compat" - fi -else -# FORT_OPT=" $FORT_OPT -auto " - FORT_OPT=" $FORT_OPT -save -zero" -fi - -FORTLOW="$FCOMP $FORT_OPT $PROFILE -O0 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTRAN="$FCOMP $FORT_OPT $PROFILE -O1 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTNA="$FCOMP $FORT_OPT -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -# for compiling free form f90 files. high opt, integer(4) -FORTF90="$FCOMP -c -O3" - -if test "$MARCDEBUG" = "ON" -then - FORTLOW="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTRAN="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTNA="$FCOMP $FORT_OPT -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -fi - -FORTLOWT="$FORTLOW" -FORTRANT="$FORTRAN" -FORTHIGHT="$FORTHIGH" - -FORTRANMNF="$FCOMP -c $FDEFINES " -CCMNF="icc -c -O1 -DLinux -DLINUX -DLinux_intel -Dport2egcs -I$MARC_SOURCE/marctoadams/mnf/include -D_LARGEFILE64_SOURCE" - -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - LOAD="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - LOADT="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - fi -# Uncomment the following lines to turn on the tracer and commnet out the next 5 lines -# if test $MPITYPE = intelmpi -# then -# INCLUDEMPI="-I$MPI_ROOT/include -I$VT_ROOT/include" -# LOAD="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# LOADT="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# fi - if test $MPITYPE = intelmpi - then - LOAD="ifort $PROFILE $LINK_OPT -o " - LOADT="ifort $PROFILE $LINK_OPT -o " - fi -else - LOAD="$FCOMP $LINK_OPT -o " - LOADT="$FCOMP $LINK_OPT -o " -fi - -if test "$MARC_DLL" = MARC_DLL -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide -lpthread" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - -if test "$AEM_DLL" -eq 1 -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - - -XLIBS="-L/usr/X11/lib -lX11 " - -# -# define archive and ranlib syntax -# - -ARC="ar rvl" -ARD="ar dvl" -ARX="ar xl" -RAN="" - -# -# choose which libraries you want to use ( e.g. blas ) -# - -if test "$VKISOLVER" = VKI -then - VKISOLVERLIBS="$MARC_LIB/vkisolver.a" -else - VKISOLVERLIBS= -fi - -if test "$CASISOLVER" = CASI -then - CASISOLVERLIBS="$CASILIB_DIR/libmarccasi.a $CASILIB_DIR/libcasi.a" -else - CASISOLVERLIBS= -fi - -MF2SOLVERLIBS= -if test "$MF2SOLVER" = MF2PARALLEL -then - MF2SOLVERLIBS="$MARC_LIB/mf2parallel/libseq.a \ - $MARC_LIB/mf2parallel/libsym.a \ - $MARC_LIB/mf2parallel/libmet.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libnum.a \ - $MARC_LIB/mf2parallel/libutl.a \ - $MARC_LIB/mf2parallel/libr8.a \ - $MARC_LIB/mf2parallel/libz.a " -fi - -if test "$MUMPSSOLVER" = MUMPS -then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - if test $MPITYPE = none - then - MUMPSSOLVERLIBS2= - echo hello > /dev/null - fi - if test $MPITYPE = intelmpi - then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a " - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a " - fi - fi - if test $MPITYPE = hpmpi - then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a" - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a" - fi - fi -else - MUMPSSOLVERLIBS= - MUMPSSOLVERLIBS2= -fi - -if test "$BCSGPUSOLVER" = BCSGPU -then - BCSSOLVERLIBS="${BCSLIB_DIR}/bcsgpulib.a " - MARCCUDALIBS1="-L${BCSLIB_DIR}/cuda_dummy -lmarccuda " - MARCCUDALIBS2="-L${BCSLIB_DIR}/cuda -lmarccuda " - MARCCUDALIBS=$MARCCUDALIBS1 -else - BCSSOLVERLIBS="${MARC_LIB}/bcslib.a " -fi -if test "$AEM_DLL" -eq 1 -then - BCSSOLVERLIBS= -fi - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - MKLLIB="$MARC_MKL/libmkl_scalapack_lp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_lp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -else - MKLLIB="$MARC_MKL/libmkl_scalapack_ilp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_ilp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -fi - -SECLIBS="-L$MARC_LIB -llapi" - -SOLVERLIBS="${BCSSOLVERLIBS} ${VKISOLVERLIBS} ${CASISOLVERLIBS} ${MF2SOLVERLIBS} \ - $MKLLIB -L$MARC_MKL -liomp5 \ - $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/kdtree2.a " - -SOLVERLIBS_DLL=${SOLVERLIBS} -if test "$AEM_DLL" -eq 1 -then -SOLVERLIBS_DLL="$MKLLIB -L$MARC_MKL -liomp5 $MARC_LIB/blas_src.a" -fi -MRCLIBS="$MARC_LIB/clib.a ${CASISOLVERLIBS}" -MRCLIBSPAR="$MARC_LIB/clib.a" -STUBS="$MARC_LIB/stubs.a " -MNFLIBS="$MARC_LIB/libmnf.a" -MDUSER="$MARC_LIB/md_user.a" -if test "X$MARC_SIMUFACT" != "X" -then - SFLIB="-L$SFMATDIR -lMBA_Grain $SFMATDIR/sfclib.a " -else - SFLIB=" " -fi - -OPENMP="-qopenmp" - -if test "$AEM_DLL" -eq 1 -then - LOAD_DLL=$LOAD - OPENMP= - LIBMNF= - OPENSSL=NONE -fi - -SYSLIBS=" $OPENMP -lpthread -shared-intel -cxxlib" - -# Uncomment the following lines to turn on the trace and comment out the next 4 lines -# if test $MPITYPE = intelmpi -# then -# SYSLIBS="-L${VT_ROOT}/lib -lVT -ldwarf -lelf -lm -lpthread \ -# -L${MPI_ROOT}/lib64 -lmpi -lmpiif -lmpigi -lrt" -# fi -if test $MPITYPE = intelmpi -then - SYSLIBS="-L${MPI_ROOT}/lib -lmpi_mt -lmpifort -lrt $OPENMP -threads -lpthread -shared-intel -cxxlib" -fi - - -SYSLIBSPAR=" " - -MARC_DLL_CODES="runmarc.f" - - -BLAS_SRC="dzero.f icopy.f izero.f" -if test "$_OEM_NASTRAN" -ne 0 -then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - BLAS_SRC="$BLAS_SRC dsctr.f zsctr.f dzasum.f daxpyi.f zaxpyi.f dgthr.f zgthr.f" - else - BLAS_SRC="ALL" - fi -fi - -LOW_OPT_CODES="are163.f contro.f ndext.f omarc.f omarca.f omarcb.f omarcc.f \ - omars.f fixbc.f triang.f bet049.f norst3.f eldata.f \ - elec*.f elct*.f fmeig.f oada00.f ogeig.f updtrbe2.f cycrota.f \ - cordef.f ogpk.f ogtan.f eldam.f formrbe3.f \ - inertie.f em_sso072.f cn_fol3d_qpatch6.f cosim_begin.f" -if test "$MARC_INTEGER_SIZE" = "i8" ; then - LOW_OPT_CODES="$LOW_OPT_CODES bbcseg.f" -fi - -HIGH_OPT_CODES="dpsmsa1.f dpsmsa2.f dpsmsa3.f dpsmsa4.f dpsmsa5.f dpsmsa6.f \ - dpsmsa7.f dpsmsa8.f dpsmsa9.f dpsmsa10.f dpsmsa11.f dpsmsa12.f \ - dpsmsa13.f dpsmsa14.f dpsmsa15.f dpsmsa16.f dpsmsah.f tpsmsah.f cn_qsort4_11.f " - - - -MAXNUM=1000000 diff --git a/installation/mods_MarcMentat/2018.1/Marc_tools/run_damask_hmp b/installation/mods_MarcMentat/2018.1/Marc_tools/run_damask_hmp deleted file mode 100644 index 24a931500..000000000 --- a/installation/mods_MarcMentat/2018.1/Marc_tools/run_damask_hmp +++ /dev/null @@ -1,4131 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -autorst auto restart flag for auto forge . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - - -# getting user subroutine file name -found=0 -for i in "$@"; do - if test $found = 1; then - DAMASK_USER=$i - found=0 - fi - case $i in - -u* | -U*) - found=1 - ;; - esac -done -# sourcing include_linux64 (needs DAMASK_USER to be set) -. $MARC_INCLUDE - -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\+\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$SFMATDIR:$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usernoext= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto=0 -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - if test ! -f $user - then - error="$error -user subroutine file $user not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$nauto" - then - if test $nauto -gt 2 - then - error="$error -incorrect option for auto restart " - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" -fi -fi - -if test $nprocd -gt 1 -then - if test $nauto -gt 0 - then - error="$error -cannot run DDM job with auto restart (-au) option " - fi -fi -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto " >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($user)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Auto Restart option ($nauto)? $ECHOTXT" - read value - if test "$value" - then - nauto=$value - fi - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# -# add DAMASK options for linking - DAMASK="-lstdc++" - - if test "$user" - then - program=$usernoext.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$usernoext.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $nauto -gt 0 -o $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $nauto -gt 0 -then - RUN_JOB="$RUN_JOB -autorst $nauto " -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -############################################################################## -# run marc using valgrind # -############################################################################## -#RUN_JOB="valgrind $RUN_JOB" -#RUN_JOB="valgrind --read-var-info=yes --gen-suppressions=yes $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=all -v $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=yes --error-limit=no $RUN_JOB" -############################################################################## - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$usermoext.o - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test $MACHINENAME = "CRAY" - then - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTHIGHMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTHIGHMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTHIGHMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - $RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2018.1/Marc_tools/run_damask_lmp b/installation/mods_MarcMentat/2018.1/Marc_tools/run_damask_lmp deleted file mode 100644 index 49b6b81fd..000000000 --- a/installation/mods_MarcMentat/2018.1/Marc_tools/run_damask_lmp +++ /dev/null @@ -1,4131 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -autorst auto restart flag for auto forge . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - - -# getting user subroutine file name -found=0 -for i in "$@"; do - if test $found = 1; then - DAMASK_USER=$i - found=0 - fi - case $i in - -u* | -U*) - found=1 - ;; - esac -done -# sourcing include_linux64 (needs DAMASK_USER to be set) -. $MARC_INCLUDE - -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\+\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$SFMATDIR:$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usernoext= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto=0 -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - if test ! -f $user - then - error="$error -user subroutine file $user not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$nauto" - then - if test $nauto -gt 2 - then - error="$error -incorrect option for auto restart " - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" -fi -fi - -if test $nprocd -gt 1 -then - if test $nauto -gt 0 - then - error="$error -cannot run DDM job with auto restart (-au) option " - fi -fi -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto " >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($user)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Auto Restart option ($nauto)? $ECHOTXT" - read value - if test "$value" - then - nauto=$value - fi - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# -# add DAMASK options for linking - DAMASK="-lstdc++" - - if test "$user" - then - program=$usernoext.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$usernoext.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $nauto -gt 0 -o $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $nauto -gt 0 -then - RUN_JOB="$RUN_JOB -autorst $nauto " -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -############################################################################## -# run marc using valgrind # -############################################################################## -#RUN_JOB="valgrind $RUN_JOB" -#RUN_JOB="valgrind --read-var-info=yes --gen-suppressions=yes $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=all -v $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=yes --error-limit=no $RUN_JOB" -############################################################################## - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$usermoext.o - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test $MACHINENAME = "CRAY" - then - $DFORTLOWMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTLOWMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_lmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTLOWMP $user || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTLOWMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_lmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTLOWMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTLOWMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - $RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2018.1/Marc_tools/run_damask_mp b/installation/mods_MarcMentat/2018.1/Marc_tools/run_damask_mp deleted file mode 100644 index f42b973cf..000000000 --- a/installation/mods_MarcMentat/2018.1/Marc_tools/run_damask_mp +++ /dev/null @@ -1,4131 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -autorst auto restart flag for auto forge . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - - -# getting user subroutine file name -found=0 -for i in "$@"; do - if test $found = 1; then - DAMASK_USER=$i - found=0 - fi - case $i in - -u* | -U*) - found=1 - ;; - esac -done -# sourcing include_linux64 (needs DAMASK_USER to be set) -. $MARC_INCLUDE - -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\+\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$SFMATDIR:$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usernoext= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto=0 -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - if test ! -f $user - then - error="$error -user subroutine file $user not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$nauto" - then - if test $nauto -gt 2 - then - error="$error -incorrect option for auto restart " - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" -fi -fi - -if test $nprocd -gt 1 -then - if test $nauto -gt 0 - then - error="$error -cannot run DDM job with auto restart (-au) option " - fi -fi -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto " >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($user)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Auto Restart option ($nauto)? $ECHOTXT" - read value - if test "$value" - then - nauto=$value - fi - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# -# add DAMASK options for linking - DAMASK="-lstdc++" - - if test "$user" - then - program=$usernoext.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$usernoext.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $nauto -gt 0 -o $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $nauto -gt 0 -then - RUN_JOB="$RUN_JOB -autorst $nauto " -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -############################################################################## -# run marc using valgrind # -############################################################################## -#RUN_JOB="valgrind $RUN_JOB" -#RUN_JOB="valgrind --read-var-info=yes --gen-suppressions=yes $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=all -v $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=yes --error-limit=no $RUN_JOB" -############################################################################## - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$usermoext.o - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test $MACHINENAME = "CRAY" - then - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTRANMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTRANMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTRANMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - $RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2018.1/Marc_tools/run_marc.original b/installation/mods_MarcMentat/2018.1/Marc_tools/run_marc.original deleted file mode 100644 index 371a3b6c6..000000000 --- a/installation/mods_MarcMentat/2018.1/Marc_tools/run_marc.original +++ /dev/null @@ -1,4209 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -autorst auto restart flag for auto forge . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - -. $MARC_INCLUDE -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\+\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$SFMATDIR:$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usersubname= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto=0 -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user - basefile=`$BASENAME $value` - if test ${basefile##*.} = f - then - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user.f - elif test ${basefile##*.} = F - then - user=`dirname $value`/`$BASENAME $value .F` - usersubname=$user.F - elif test ${basefile##*.} = f90 - then - user=`dirname $value`/`$BASENAME $value .f90` - usersubname=$user.f90 - elif test ${basefile##*.} = F90 - then - user=`dirname $value`/`$BASENAME $value .F90` - usersubname=$user.F90 - fi - case $user in - \/*) - ;; - *) - user=`pwd`/$user - usersubname=`pwd`/$usersubname - ;; - esac - if test ! -f $usersubname - then - if test -f $usersubname.f - then - usersubname=$usersubname.f - elif test -f $usersubname.F - then - usersubname=$usersubname.F - elif test -f $usersubname.f90 - then - usersubname=$usersubname.f90 - elif test -f $usersubname.F90 - then - usersubname=$usersubname.F90 - fi - fi - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$usersubname" - then - if test ! -f $usersubname - then - error="$error -user subroutine file $usersubname not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$nauto" - then - if test $nauto -gt 2 - then - error="$error -incorrect option for auto restart " - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" - fi -fi - -if test $nprocd -gt 1 -then - if test $nauto -gt 0 - then - error="$error -cannot run DDM job with auto restart (-au) option " - fi -fi -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $usersubname -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto " >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $usersubname -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($usersubname)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user - basefile=`$BASENAME $value` - if test ${basefile##*.} = f - then - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user.f - elif test ${basefile##*.} = F - then - user=`dirname $value`/`$BASENAME $value .F` - usersubname=$user.F - elif test ${basefile##*.} = f90 - then - user=`dirname $value`/`$BASENAME $value .f90` - usersubname=$user.f90 - elif test ${basefile##*.} = F90 - then - user=`dirname $value`/`$BASENAME $value .F90` - usersubname=$user.F90 - fi - case $user in - \/*) - ;; - *) - user=`pwd`/$user - usersubname=`pwd`/$usersubname - ;; - esac - if test ! -f $usersubname - then - if test -f $usersubname.f - then - usersubname=$usersubname.f - elif test -f $usersubname.F - then - usersubname=$usersubname.F - elif test -f $usersubname.f90 - then - usersubname=$usersubname.f90 - elif test -f $usersubname.F90 - then - usersubname=$usersubname.F90 - fi - fi - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Auto Restart option ($nauto)? $ECHOTXT" - read value - if test "$value" - then - nauto=$value - fi - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# - - if test "$user" - then -# program=$user.marc - program=$DIRJOB/`$BASENAME $user .f`.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$DIRJOB/`$BASENAME $user .f`.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $nauto -gt 0 -o $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $nauto -gt 0 -then - RUN_JOB="$RUN_JOB -autorst $nauto " -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -############################################################################## -# run marc using valgrind # -############################################################################## -#RUN_JOB="valgrind $RUN_JOB" -#RUN_JOB="valgrind --read-var-info=yes --gen-suppressions=yes $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=all -v $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=yes --error-limit=no $RUN_JOB" -############################################################################## - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$DIRJOB/`$BASENAME $user .f`.o - basefile=`$BASENAME $usersubname` - if test ${basefile##*.} = f - then - usersub=$DIRJOB/`$BASENAME $user .f`.F - ln -sf "$user.f" "$usersub" - else - usersub=$usersubname - fi - - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test ${basefile##*.} = f - then - ln -sf "$user.f" "$usersub" - fi - if test $MACHINENAME = "CRAY" - then - $FORTRAN $usersub || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $FORTRAN $usersub -o $userobj || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - if test ${basefile##*.} = f - then - /bin/rm -f "$usersub" - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=`basename $usersubname .f` - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user.f $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user.f on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser.f 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user.f on host `hostname`" - fi - userobj=$DIRJOB/`$BASENAME $user .f`.o - basefile=`$BASENAME $usersubname` - if test ${basefile##*.} = f - then - usersub=$DIRJOB/`$BASENAME $user .f`.F - ln -sf "$user.f" "$usersub" - else - usersub=$usersubname - fi - if test $MACHINENAME = "CRAY" - then - $FORTRAN $usersub || \ - { - echo "$0: compile failed for $user.f" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $FORTRAN $usersub -o $userobj || \ - { - echo "$0: compile failed for $user.f" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - if test ${basefile##*.} = f - then - /bin/rm -f "$usersub" - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi - fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=`basename $usersubname .f` - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user.f $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user.f on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser.f 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user.f on host `hostname`" - fi - userobj=$DIRJOB/`$BASENAME $user .f`.o - basefile=`$BASENAME $usersubname` - if test ${basefile##*.} = f - then - usersub=$DIRJOB/`$BASENAME $user .f`.F - ln -sf "$user.f" "$usersub" - else - usersub=$usersubname - fi - if test $MACHINENAME = "CRAY" - then - $FORTRAN $usersub || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $FORTRAN $usersub -o $userobj || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - if test ${basefile##*.} = f - then - /bin/rm -f "$usersub" - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null - -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - -$RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi - fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=`basename $usersubname .f` - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2018.1/Mentat_bin/edit_window b/installation/mods_MarcMentat/2018.1/Mentat_bin/edit_window deleted file mode 100644 index b732a7694..000000000 --- a/installation/mods_MarcMentat/2018.1/Mentat_bin/edit_window +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -# This script opens a window running an editor. -# The command to invoke the editor is specified during DAMASK installation - -%EDITOR% $* \ No newline at end of file diff --git a/installation/mods_MarcMentat/2018.1/Mentat_bin/edit_window.original b/installation/mods_MarcMentat/2018.1/Mentat_bin/edit_window.original deleted file mode 100644 index 64c0a68d0..000000000 --- a/installation/mods_MarcMentat/2018.1/Mentat_bin/edit_window.original +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh -# This script opens a window running an editor. The default window is an -# xterm, and the default editor is vi. These may be customized. - -dir= -for d in /usr/bin /usr/bin/X11; do - if test -x "$d/xterm"; then - dir="$d" - break - fi -done - -if test -z "$dir"; then - echo "$0: Could not find xterm" - exit 1 -fi - -"$dir/xterm" -T "vi $*" -n "vi $*" -e vi $* diff --git a/installation/mods_MarcMentat/2018.1/Mentat_bin/kill1.original b/installation/mods_MarcMentat/2018.1/Mentat_bin/kill1.original deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2018.1/Mentat_bin/kill1.original +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2018.1/Mentat_bin/kill4 b/installation/mods_MarcMentat/2018.1/Mentat_bin/kill4 deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2018.1/Mentat_bin/kill4 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2018.1/Mentat_bin/kill5 b/installation/mods_MarcMentat/2018.1/Mentat_bin/kill5 deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2018.1/Mentat_bin/kill5 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2018.1/Mentat_bin/kill6 b/installation/mods_MarcMentat/2018.1/Mentat_bin/kill6 deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2018.1/Mentat_bin/kill6 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2018.1/Mentat_bin/submit1.original b/installation/mods_MarcMentat/2018.1/Mentat_bin/submit1.original deleted file mode 100644 index ff6ba14bd..000000000 --- a/installation/mods_MarcMentat/2018.1/Mentat_bin/submit1.original +++ /dev/null @@ -1,186 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=/tmp/msc/marc2018.1 -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -autorst=$4 -copy_datfile="-ci $5" -copy_postfile="-cr $6" -scr_dir=$7 -dcoup=$8 -assem_recov_nthread=$9 -shift 9 # cannot use $10, $11, ... -nthread=$1 -nsolver=$2 -mode=$3 -gpu=$4 - -if [ "$slv" != "" -a "$slv" != "marc" ]; then - slv="-iam sfm" -else - slv="" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_marc" $slv -j $job -v n -b y $nprocds $nprocd -autorst $autorst \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2018.1/Mentat_bin/submit4 b/installation/mods_MarcMentat/2018.1/Mentat_bin/submit4 deleted file mode 100644 index f25a2004e..000000000 --- a/installation/mods_MarcMentat/2018.1/Mentat_bin/submit4 +++ /dev/null @@ -1,187 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=%INSTALLDIR%/marc%VERSION% -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -autorst=$4 -copy_datfile="-ci $5" -copy_postfile="-cr $6" -scr_dir=$7 -dcoup=$8 -assem_recov_nthread=$9 -shift 9 # cannot use $10, $11, ... -nthread=$1 -nsolver=$2 -mode=$3 -gpu=$4 - -if [ "$slv" != "" -a "$slv" != "marc" ]; then - slv="-iam sfm" -else - slv="" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile=${srcfile%.*}".marc" - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_damask_hmp" $slv -j $job -v n -b y $nprocds $nprocd -autorst $autorst \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2018.1/Mentat_bin/submit5 b/installation/mods_MarcMentat/2018.1/Mentat_bin/submit5 deleted file mode 100644 index 786f6efc5..000000000 --- a/installation/mods_MarcMentat/2018.1/Mentat_bin/submit5 +++ /dev/null @@ -1,187 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=%INSTALLDIR%/marc%VERSION% -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -autorst=$4 -copy_datfile="-ci $5" -copy_postfile="-cr $6" -scr_dir=$7 -dcoup=$8 -assem_recov_nthread=$9 -shift 9 # cannot use $10, $11, ... -nthread=$1 -nsolver=$2 -mode=$3 -gpu=$4 - -if [ "$slv" != "" -a "$slv" != "marc" ]; then - slv="-iam sfm" -else - slv="" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile=${srcfile%.*}".marc" - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_damask_mp" $slv -j $job -v n -b y $nprocds $nprocd -autorst $autorst \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2018.1/Mentat_bin/submit6 b/installation/mods_MarcMentat/2018.1/Mentat_bin/submit6 deleted file mode 100644 index 6a5d9d79f..000000000 --- a/installation/mods_MarcMentat/2018.1/Mentat_bin/submit6 +++ /dev/null @@ -1,187 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=%INSTALLDIR%/marc%VERSION% -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -autorst=$4 -copy_datfile="-ci $5" -copy_postfile="-cr $6" -scr_dir=$7 -dcoup=$8 -assem_recov_nthread=$9 -shift 9 # cannot use $10, $11, ... -nthread=$1 -nsolver=$2 -mode=$3 -gpu=$4 - -if [ "$slv" != "" -a "$slv" != "marc" ]; then - slv="-iam sfm" -else - slv="" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile=${srcfile%.*}".marc" - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_damask_lmp" $slv -j $job -v n -b y $nprocds $nprocd -autorst $autorst \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2018.1/Mentat_menus/job_run.ms b/installation/mods_MarcMentat/2018.1/Mentat_menus/job_run.ms deleted file mode 100644 index 674cd3aae..000000000 --- a/installation/mods_MarcMentat/2018.1/Mentat_menus/job_run.ms +++ /dev/null @@ -1,2703 +0,0 @@ -#ifndef AUTOFORGE -popmenu job_title_pm file jobs.ms -popdown job_title_ok file jobs.ms - -group user_domains_gr file domain_decomposition.ms -group user_domains_generate_gr file domain_decomposition.ms -group user_domains_tail_gr file domain_decomposition.ms -group matrix_solver_gr file job_common.ms -popmenu ddm_options file job_common.ms - -browser edit_browser file file.ms -browser directory_browser file file.ms -screen domains file domain_decomposition.ms - - - - browser usersub_file_browser { - position 0 0 - size 82 72 - text "$usersub_file_browser_label" ($usersub_file_browser_label) - filter "*.f *.F *.f90 *.F90" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$usersub_file_browser_command" ($usersub_file_browser_command) - } - - - - browser host_file_browser { - position 0 0 - size 82 72 - text "$host_file_browser_label" ($host_file_browser_label) - filter "*" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$host_file_browser_command" ($host_file_browser_command) - } - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_popmenu { - - text "RUN JOB" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - button { - position 1 9 - size 24 4 - text "USER SUBROUTINE FILE" - browser usersub_file_browser - settext $usersub_file_browser_label "SELECT USER SUBROUTINE FILE" - set $usersub_file_browser_command "*job_usersub_file" - help job_usersub_file - } - - toggle { - position +26 = - size 22 4 - text "SELECTED USER SUBS" - toggle job_usersubs - help job_run_seluser - visible job_usersubs - popmenu job_usersub_pm - } - - display { - position 1 +4 - size 50 4 - display job_usersub_file - } - - button { - position 1 +4 - size 12 4 - text "EDIT" - command "*job_edit_usersub_file" - visible job_usersub_file - } - - button { - position +12 = - size 12 4 - text "CLEAR" - command "*job_clear_usersub_file" - visible job_usersub_file - } - - roller { - position +12 = - size 26 4 - nvalues 3 - texts "COMPILE / NO SAVE" - "COMPILE AND SAVE" - "RUN SAVED EXECUTABLE" - help job_run_compile - roller "job_option user_source" - visible job_usersub_file - commands "*job_option user_source:compile_nosave" - "*job_option user_source:compile_save" - "*job_option user_source:run_saved" - } - - button { - position 1 +6 - size 24 4 - text "SOLVER/PARALLELIZATION" - help job_run_parallel - popmenu job_run_parallelization_pm - set $popname2 "job_run_parallelization_pm" - } - frame { - position 1 +4 - size 48 16 - border_width 1 - border_color black - - group{ - layout hbox - frame { - position 0 0 - size 24 16 - group { - layout vbox - - display { - position 0 0 - size 24 4 - display job_solver_solution - } - - display { - position = +4 - size 24 4 - display job_solver_type - } - spacer { - stretch 1 - } - - } - } - - frame { - position +22 = - size 24 16 - border_width 1 - border_color black - - group { - #layout vbox - display { - position = +4 - size 24 4 - display job_ddm_domains - } - - display { - position = +4 - size 24 4 - display job_assem_recov_nthreads - } - - display { - position = +4 - size 24 4 - display job_solver_procs - visible solver_allows_multi_procs - } - - display { - position = = - size 24 4 - display job_solver_threads - visible "and(solver_allows_multi_threads,\ - not(and(job_solver_mfront_sparse,\ - *job_option parallel:on)))" - } - - display { - position = +4 - size 24 4 - display job_solver_gpu - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } - } - } - } - } - - button { - position 1 +18 - size 8 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - -# see also job_common.ms -# see also the ADVANCED JOB SUBMISSION popmenu in this file - - label { - position +10 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - button { - position +20 = - size 13 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position 1 +6 - size 16 6 - text "SUBMIT (1)" - command "*submit_job 1 *monitor_job" - } - - button { - position +16 = - size 16 6 - text "ADVANCED JOB SUBMISSION" - popmenu job_submit_adv_pm - } - - button { - position +16 = - size 18 6 - text "DAMASK" - popmenu damask - } - - button { - position 1 +6 - size 16 6 - text "UPDATE" - command "*update_job" - } - - button { - position +16 = - size 16 6 - text "MONITOR" - command "*monitor_job" - } - - button { - position +16 = - size 18 6 - text "KILL" - command "*kill_job *monitor_job" - } - - label { - position 1 +7 - size 32 4 - text "STATUS" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_status" - } - - label { - position -32 +4 - size 32 4 - text "CURRENT INCREMENT (CYCLE)" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_increment" - } - - label { - position -32 +4 - size 32 4 - text "SINGULARITY RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_singularity_ratio" - } - - label { - position -32 +4 - size 32 4 - text "CONVERGENCE RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_convergence_ratio" - } - - label { - position 1 +4 - size 32 4 - text "ANALYSIS TIME" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_analysis_time" - } - - label { - position -32 +4 - size 32 4 - text "WALL TIME" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_time" - } - - frame { - position 1 +4 - size 50 8 - - group { - - frame { - position 0 0 - size 50 8 - text "TOTAL" - border_width 1 - border_color black - group { - - label { - position +6 = - size 13 4 - text "CYCLES" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_cycles" - border_width 1 - border_color black - } - - label { - position -13 +4 - size 13 4 - text "SEPARATIONS" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_separations" - border_width 1 - border_color black - } - - label { - position +10 -4 - size 11 4 - text "CUT BACKS" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_cut_backs" - border_width 1 - border_color black - } - - label { - position -11 +4 - size 11 4 - text "REMESHES" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_remeshes" - border_width 1 - border_color black - } - } - } - } - } - - label { - position 1 +8 - size 19 4 - text "EXIT NUMBER" - border_width 1 - border_color black - } - - integer { - position +19 = - size 10 4 - display "job_exit" - } - - button { - position +10 = - size 21 4 - text "EXIT MESSAGE" - popmenu job_exit_msg_pm - help exit_message - } - - label { - position 1 +6 - size 7 4 - text "EDIT" - border_width 1 - border_color black - } - - button { - position +7 = - size 12 4 - text "OUTPUT FILE" - command "*job_edit_output" - } - - button { - position +12 = - size 9 4 - text "LOG FILE" - command "*job_edit_log_file" - } - - button { - position +9 = - size 12 4 - text "STATUS FILE" - command "*job_edit_status_file" - } - - button { - position +12 = - size 10 4 - text "ANY FILE" - settext $edit_browser_label "EDIT FILE" - set $edit_browser_command "*edit_file" - browser edit_browser - help edit_file - } - - popdown { - position 1 +6 - size 32 4 - text "OPEN POST FILE (MODEL PLOT RESULTS MENU)" - command "@popdown(job_properties_pm) @main(results) @popup(modelplot_pm) *post_open_default" - } - - button { - position 1 +6 - size 12 8 - text "RESET" - command "*job_submit_reset" - } - - popdown { - position +38 = - size 12 8 - text "OK" - } - } - - window job_run_wi { - parent mentat - origin 35 1 - size 52 115 - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_usersub_pm { - - text "CURRENTLY SELECTED USER SUBROUTINES" - - group { - - - display { - position 1 +5 - size 64 86 - display "job_usersubs" - } - - popdown { - position 27 +88 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 66 102 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_submit_adv_pm { - - text "ADVANCED JOB SUBMISSION" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - label { - position 1 9 - size 19 4 - text "INITIAL ALLOCATION" - border_width 1 - border_color black - } - label { - position +19 = - size 15 4 - text "GENERAL MEMORY" - help job_param_general_init_allocation - } - text { - position +15 = - size 10 4 - display "job_param_value_general_init_allocation" - command "*job_param general_init_allocation" - help job_param_general_init_allocation - } - - label { - position +10 = - size 4 4 - text "MB" - border_width 1 - border_color black - } - - toggle { - position 1 +5 - size 32 4 - text "OUT-OF-CORE ELEMENT STORAGE" - help job_param_elsto - toggle "*job_option elsto:on" - true_command "*job_option elsto:on" - false_command "*job_option elsto:off" - } - - toggle { - position 1 +4 - size 32 4 - text "OUT-OF-CORE INCREMENTAL BACKUP" - help job_param_inc_backup_storage - toggle "*job_option inc_backup_storage:out_of_core" - true_command "*job_option inc_backup_storage:out_of_core" - false_command "*job_option inc_backup_storage:in_core" - } - - toggle { - position +34 = - size 14 4 - text "CHECK SIZES" - help job_run_check - toggle "*job_option check:on" - true_command "*job_option check:on" - false_command "*job_option check:off" - } - - frame { - position 1 +6 - size 48 12 - text "MARC INPUT FILE" - border_width 1 - border_color black - - group { - - label { - position 0 4 - size 9 4 - text "VERSION" - border_width 1 - border_color black - } - - roller { - position +9 = - size 14 4 - nvalues 26 - nvisible 26 - texts "DEFAULT" -#if 0 - "2018.1" -#endif - "2018" - "2017.1" - "2017" - "2016" - "2015" - "2014.2" - "2014.1" - "2014" - "2013.1" - "2013" - "2012" - "2011" - "2010.2" - "2010" - "2008" - "2007" - "2005R3" - "2005" - "2003" - "2001" - "2000" -#if 0 - "8" -#endif - "K7" - "K6.2" - "K5" - "K4" - help job_param_version - rollers "job_input_version_default" -#if 0 - "job_input_version_2018.1" -#endif - "job_input_version_2018" - "job_input_version_2017.1" - "job_input_version_2017" - "job_input_version_2016" - "job_input_version_2015" - "job_input_version_2014.2" - "job_input_version_2014.1" - "job_input_version_2014" - "job_input_version_2013.1" - "job_input_version_2013" - "job_input_version_2012" - "job_input_version_2011" - "job_input_version_2010.2" - "job_input_version_2010" - "job_input_version_2008" - "job_input_version_2007" - "job_input_version_2005r3" - "job_input_version_2005" - "job_input_version_2003" - "job_input_version_2001" - "job_input_version_2000" -#if 0 - "job_input_version_8" -#endif - "job_input_version_k7" - "job_input_version_k6" - "job_input_version_k5" - "job_input_version_k4" - commands "*job_option version:default" -#if 0 - "*job_option version:2018.1" -#endif - "*job_option version:2018" - "*job_option version:2017.1" - "*job_option version:2017" - "*job_option version:2016" - "*job_option version:2015" - "*job_option version:2014.2" - "*job_option version:2014.1" - "*job_option version:2014" - "*job_option version:2013.1" - "*job_option version:2013" - "*job_option version:2012" - "*job_option version:2011" - "*job_option version:2010.2" - "*job_option version:2010" - "*job_option version:2008" - "*job_option version:2007" - "*job_option version:2005r3" - "*job_option version:2005" - "*job_option version:2003" - "*job_option version:2001" - "*job_option version:2000" -#if 0 - "*job_option version:8" -#endif - "*job_option version:k7" - "*job_option version:k6" - "*job_option version:k5" - "*job_option version:k4" - visibles "job_allows_input_version_default" -#if 0 - "job_allows_input_version_2018.1" -#endif - "job_allows_input_version_2018" - "job_allows_input_version_2017.1" - "job_allows_input_version_2017" - "job_allows_input_version_2016" - "job_allows_input_version_2015" - "job_allows_input_version_2014.2" - "job_allows_input_version_2014.1" - "job_allows_input_version_2014" - "job_allows_input_version_2013.1" - "job_allows_input_version_2013" - "job_allows_input_version_2012" - "job_allows_input_version_2011" - "job_allows_input_version_2010.2" - "job_allows_input_version_2010" - "job_allows_input_version_2008" - "job_allows_input_version_2007" - "job_allows_input_version_2005r3" - "job_allows_input_version_2005" - "job_allows_input_version_2003" - "job_allows_input_version_2001" - "job_allows_input_version_2000" -#if 0 - "job_allows_input_version_8" -#endif - "job_allows_input_version_k7" - "job_allows_input_version_k6" - "job_allows_input_version_k5" - "job_allows_input_version_k4" - } - -# see also job_common.ms -# see also the RUN JOB popmenu in this file - - label { - position +14 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - toggle { - position 0 +4 - size 24 4 - text "EXTENDED PRECISION" - help job_run_precision - toggle "*job_option inp_file_prec:extended" - true_command "*job_option inp_file_prec:extended" - false_command "*job_option inp_file_prec:normal" - } - toggle { - position +24 = - size 24 4 - text "INCLUDE UNUSED TABLES" - toggle "*job_option input_file_tables:all" - true_command "*job_option input_file_tables:all" - false_command "*job_option input_file_tables:used" - } - } - } - - button { - position 1 +14 - size 24 4 - text "SCRATCH DIRECTORY" - settext $directory_browser_label "JOB SCRATCH DIRECTORY" - set $directory_browser_command "*job_scratch_directory" - browser directory_browser - help job_scratch_directory - } - - button { - position +24 = - size 24 4 - text "CLEAR" - command "*job_clear_scratch_directory" - visible job_scratch_directory - } - - text { - position 1 +4 - size 48 4 - display job_scratch_dir - command "*job_scratch_directory" - } - -#ifdef DCOM - toggle { - position 1 +6 - size 8 4 - text "\{DCOM}" - toggle "*job_option dcom:on" - help job_run_dcom - true_command "*job_option dcom:on" - false_command "*job_option dcom:off" - visible win32_available - } - - button { - position +8 = - size 12 4 - text "HOSTNAME" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } - - text job_dcom_hostname { - position +12 = - size 28 4 - display "job_dcom_hostname" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } -#endif - - button { - position 1 +6 - size 24 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - - button { - position +24 = - size 24 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position +4 +6 - size 20 4 - text "WRITE INPUT FILE" - command "*job_write_input" - } - - button { - position = +4 - size 20 4 - text "EDIT INPUT FILE" - command "*job_edit_input" - } - - popdown { - position 1 +5 - size 20 6 - text "SUBMIT 1" - command "*submit_job 1 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 1" - command "*execute_job 1 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 2" - command "*submit_job 2 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 2" - command "*execute_job 2 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 3" - command "*submit_job 3 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 3" - command "*execute_job 3 *monitor_job" - } - - popdown { - position 19 +8 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 -#ifdef DCOM - size 50 100 -#else - size 50 94 -#endif - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - -#-------------------------------------------------------------------------------------------------- -popmenu damask { - -#ifdef QT_MENTAT - text "DAMASK.MPIE.DE" -#endif - - group { -#ifndef QT_MENTAT - label { - position 0 0 - size 50 4 - text "DAMASK.MPIE.DE" - } -#endif - - label { - position 1 6 - size 13 6 - text "Optimzation" - border_width 1 - border_color black - } - - label { - position +13 = - size 20 6 - text "write Input" - border_width 1 - border_color black - } - - label { - position +18 = - size 30 6 - text "do not write Inp." - border_width 1 - border_color black - } - - label { - position -32 +6 - size 12 6 - text "O2 / OpenMP" - border_width 1 - border_color black - } - - popdown { - position +12 = - size 20 6 - text "Submit" - command "*submit_job 4 *monitor_job" - } - - popdown { - position +20 = - size 20 6 - text "Execute" - command "*execute_job 4 *monitor_job" - } - - label { - position -32 +6 - size 12 6 - text "O1 / OpenMP" - border_width 1 - border_color black - } - - popdown { - position +12 = - size 20 6 - text "Submit" - command "*submit_job 5 *monitor_job" - } - - popdown { - position +20 = - size 20 6 - text "Execute" - command "*execute_job 5 *monitor_job" - } - - label { - position -32 +6 - size 12 6 - text "O0 / OpenMP" - border_width 1 - border_color black - } - - popdown { - position +12 = - size 20 6 - text "Submit" - command "*submit_job 6 *monitor_job" - } - - popdown { - position +20 = - size 20 6 - text "Execute" - command "*execute_job 6 *monitor_job" - } - - popdown { - position 19 +8 - size 12 8 - text "CANCEL" - } -} - - window { - parent mentat - origin 38 8 -#ifdef DCOM - size 50 100 -#else - size 50 94 -#endif - background_color body - border_width 1 - border_color border - buffering single - } - mode permanent -} - -#-------------------------------------------------------------------------------------------------- -popmenu job_exit_msg_pm { - - text "EXIT MESSAGE" - - group { - - - - text { - position 1 5 - size 84 74 - multiline - readonly - display "job_exit_msg" - } - - popdown { - position 37 +76 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 86 90 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_parallelization_pm { - - text "SOLVER/PARALLELIZATION" - - group { - layout vbox - frame { - position 0 0 - size 42 8 - group { - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 36 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 36 4 - display job_class_label - } - } - } - frame { - position 0 8 - size 42 20 - group job_ddm_gr - text "DOMAIN DECOMPOSITION" - border_width 1 - border_color black - } - - frame { - position 0 +20 - size 42 13 - group job_assem_recov_gr - text "ASSEMBLY AND RECOVERY" - border_width 1 - border_color black - } - - frame { - position 0 +14 - size 42 31 - group job_parallel_matrix_solver_gr - text "MATRIX SOLVER" - border_width 1 - border_color black - } - - frame { - position 0 +32 - size 42 28 - group job_parallel_env_gr - text "PARALLELIZATION ENVIRONMENT" - border_width 1 - border_color black - visible "or(*job_option parallel:on, \ - solver_multi_procs)" - } - frame { - position 15 +30 - size 42 8 - group { - layout hbox - - spacer { - stretch 1 - } - popdown { - position 15 0 - size 12 8 - text "OK" - } - spacer { - stretch 1 - } - } - } - - spacer { - spacing 2 - stretch 1 - } - } - - window { - parent mentat - origin 38 1 - size 60 119 - background_color body - border_width 1 - border_color border - buffering single - } - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_gr { - - toggle { - position 1 4 - size 42 4 - text "USE \{DDM}" - toggle "*job_option parallel:on" - help job_run_ddm_use - true_command "*job_option parallel:on" - false_command "*job_option parallel:off" - active "and(not(job_solver_it_ext),\ - not(job_solver_mixed_direct_iterative))" - } - - frame { - position = +5 - size 42 4 - group job_ddm_use_gr - visible "*job_option parallel:on" - } -} - -group job_ddm_use_gr { - layout vbox - frame{ - position 0 0 - size 30 4 - group { - layout hbox - label { - position 0 0 - size 12 4 - text "DECOMPOSITION IN" - help job_run_ddm_generator - } - oneonly{ - position +12 = - size 8 4 - text "MARC" - oneonly "*job_option ddm_generator:fea_solver" - command "*job_option ddm_generator:fea_solver" - help job_run_ddm_generator - } - oneonly{ - position +12 = - size 8 4 - text "MENTAT" - oneonly "*job_option ddm_generator:preprocessor" - command "*job_option ddm_generator:preprocessor" - help job_run_ddm_generator - } - } - } - - frame { - position 0 +5 - size 44 8 - group job_ddm_fea_solver_gr - visible "*job_option ddm_generator:fea_solver" - } - - frame { - position = = - size 44 8 - group job_ddm_preprocessor_gr - visible "*job_option ddm_generator:preprocessor" - } - - frame{ - position 0 +5 - size 40 4 - group{ - layout hbox - text { - position 0 0 - size 22 4 - text "Single Input File" - readonly - visible "*job_option ddm_generator:fea_solver" - } - - roller { - position = = - size 22 4 - nvalues 2 - texts "MULTIPLE INPUT FILES" - "SINGLE INPUT FILE" - roller "job_option ddm_single_input" - commands "*job_option ddm_single_input:off" - "*job_option ddm_single_input:on" - visible "*job_option ddm_generator:preprocessor" - help job_run_ddm_single_input - } - - roller { - position +23 = - size 21 4 - nvalues 2 - texts "MULTIPLE POST FILES" - "SINGLE POST FILE" - roller "job_option ddm_single_post" - commands "*job_option ddm_single_post:off" - "*job_option ddm_single_post:on" - help job_run_ddm_single_post - } - } - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_fea_solver_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - help job_param - } - - text { - position +10 = - size 4 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 0 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - button { - position +18 = - size 12 4 - text "ADV. SETTINGS" - popmenu job_ddm_fea_solver_pm - } -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_ddm_fea_solver_pm { - - text "JOB PARALLELIZATION" - - group { - units 32 120 - - - label { - position 0 5 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - frame { - - position 0 +9 - size 32 76 - text "ADVANCED DECOMPOSITION IN MARC" - border_width 1 - border_color black - - group { - - label { - position 1 4 - size 16 4 - text "# DOMAINS" - help job_param - } - - text { - position +16 = - size 14 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 1 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 23 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - frame { - position 1 +5 - size 30 20 - group job_ddm_direction_gr - visible "or(*job_option ddm_method:vector, \ - *job_option ddm_method:radial, \ - *job_option ddm_method:angular)" - } - - toggle { - position 1 +21 - size 30 4 - text "DOMAIN ISLAND REMOVAL" - toggle "*job_option ddm_island_removal:on" - true_command "*job_option ddm_island_removal:on" - false_command "*job_option ddm_island_removal:off" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "GRAPH" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "COARSE" - "FINE" - help ddm_decomp_coarse_graph - rollers "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - commands "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "QUADRATIC ELEMENTS" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "GENUINE" - "LINEARIZED" - help job_run_ddm_decomp_linearized - rollers "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - commands "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - } - - label { - position 1 +5 - size 15 4 - text "ELEMENT WEIGHT FACTOR" - help job_param - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_elem_weight_factor" - command "*job_param ddm_elem_weight_factor" - help job_run_ddm_decomp_element_weight_factor - } - - toggle { - position 1 +5 - size 30 4 - text "DETECT CONTACT" - toggle "*job_option ddm_detect_contact:on" - true_command "*job_option ddm_detect_contact:on" - false_command "*job_option ddm_detect_contact:off" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - help job_run_ddm_decomp_detect_contact - } - - label { - position = +5 - size 15 4 - text "CONTACT TOLERANCE" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - command "*set_ddm_contact_tolerance" - display "job_param_value_ddm_contact_tolerance" - command "*job_param ddm_contact_tolerance" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_tolerance - } - - label { - position -15 +4 - size 15 4 - text "CONTACT CONSTR FACTOR" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_contact_constr_factor" - command "*job_param ddm_contact_constr_factor" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_constraint_factor - } - } - } - - popdown { - position 0 +77 - size 32 8 - text "OK" - } - } - mode permanent -} # job_ddm_fea_solver_pm - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_direction_gr { - - button { - position 0 0 - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "*job_option ddm_method:vector" - } - - button { - position = = - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "not(*job_option ddm_method:vector)" - } - - button { - position +15 = - size 15 4 - text "FROM / TO" - command "*job_vector_from_to ddm_sort_direction_x" - } - - text { - position -15 +4 - size 10 4 - command "*job_param ddm_sort_direction_x" - display "job_param_value_ddm_sort_direction_x" - help ddm_job_decomp_user_direction_x - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_y" - display "job_param_value_ddm_sort_direction_y" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_z" - display "job_param_value_ddm_sort_direction_z" - } - - frame { - position 0 +4 - size 30 8 - group job_ddm_sort_point_gr - visible "not(*job_option ddm_method:vector)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_sort_point_gr { - - label { - position 0 0 - size 14 4 - border_width 1 - border_color black - text "POINT ON AXIS" - } - - roller { - position +14 = - size 10 4 - nvalues 2 - texts "DEFAULT" - "USER" - roller "job_option ddm_sort_point" - commands "*job_option ddm_sort_point:default" - "*job_option ddm_sort_point:user" - } - - button { - position +10 = - size 6 4 - text "SET" - command "*job_position ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position 0 +4 - size 10 4 - command "*job_param ddm_sort_point_x" - display "job_param_value_ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_y" - display "job_param_value_ddm_sort_point_y" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_z" - display "job_param_value_ddm_sort_point_z" - visible "*job_option ddm_sort_point:user" - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_preprocessor_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - border_width 1 - border_color black - } - - integer { - position +10 = - size 4 4 - display valid_domains - } - - button { - position 0 +4 - size 30 4 - text "USER DOMAINS" - popmenu domains_pm - help job_run_ddm_user_domains - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_assem_recov_gr { - - toggle { - position 1 +4 - size 30 4 - text "MULTIPLE THREADS" - true_command "*job_option assem_recov_multi_threading:on" - false_command "*job_option assem_recov_multi_threading:off" - toggle "*job_option assem_recov_multi_threading:on" - } - - label { - position = +4 - size 12 4 - text "# THREADS" - visible "*job_option assem_recov_multi_threading:on" - } - - text { - position +12 = - size 4 4 - display "job_param_value_assem_recov_nthreads" - command "*job_param assem_recov_nthreads" - visible "*job_option assem_recov_multi_threading:on" - } - - label { - position +4 = - size 10 4 - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - } - - display { - position +12 = - size 4 4 - display "job_assem_recov_nthreads_dom" - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - } - spacer{ - stretch 2 - } - -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_matrix_solver_gr { - layout vbox - frame { - position 1 0 - size 36 31 - group { - layout hbox - label { - position 3 4 - size 12 4 - text "SOLUTION" - border_width 1 - border_color black - } - oneonly { - position +12 = - size 12 4 - text "SYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_off" - command "*job_option solver_nonsym:off" - } - oneonly { - position +12 = - size 12 4 - text "NONSYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_on" - command "*job_option solver_nonsym:on" - } - spacer { - stretch 1 - } - } - } - - frame { - position 1 +5 - size 42 23 - group matrix_solver_gr - help job_param_solver - } - - frame { - position +1 = - size 42 4 - group job_run_solver_ddm_opts_gr - visible "*job_option parallel:on" - } - - frame { - position 1 +23 - size 42 8 - group job_solver_multi_procs_gr - visible solver_allows_multi_procs - } - - frame { - position = = - size 42 8 - group job_solver_multi_threads_gr - visible solver_allows_multi_threads - } - - frame { - position 1 +9 - size 42 8 - group job_solver_gpu_gr - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_run_solver_ddm_opts_gr { - - button { - position 0 0 - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options -# see also job_common.ms! - visible "not(or(job_solver_it_sparse, \ - job_solver_it_ext, \ - job_solver_mixed_direct_iterative, \ - job_solver_pardiso,\ - job_solver_mumps))" - } - button { - position = = - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options_mumps - visible "job_solver_mumps" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_gr { - frame { - position 0 0 - size 42 8 - group job_solver_multi_procs_parallel_off_gr - visible "*job_option parallel:off" - } - - frame { - position = = - size 42 8 - group job_solver_multi_procs_parallel_on_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - true_command "*job_option nsolver_procs_serial:on" - false_command "*job_option nsolver_procs_serial:off" - toggle "*job_option nsolver_procs_serial:on" - help job_run_multithreading - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - visible "*job_option nsolver_procs_serial:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - visible "*job_option nsolver_procs_serial:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - border_width 1 - border_color black - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - help job_run_multithreading - rollers "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_nsolver_procs_ddm_automatic_gr - visible "*job_option nsolver_procs_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_nsolver_procs_ddm_user_gr - visible "*job_option nsolver_procs_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - } -} - -group job_solver_multi_threads_gr { - frame { - position 0 0 - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_off_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:off)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_on_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:on)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_pardiso_parallel_off_gr - visible "and(job_solver_pardiso,*job_option parallel:off)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_pardiso_parallel_on_gr - visible "and(job_solver_pardiso,*job_option parallel:on)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_it_ext_off_gr - visible "and(job_solver_it_ext,*job_option parallel:off)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option mfront_sparse_multi_threading:on" - true_command "*job_option mfront_sparse_multi_threading:on" - false_command "*job_option mfront_sparse_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option mfront_sparse_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option mfront_sparse_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +30 0 - size 12 4 - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - } - - display { - position +12 0 - size 4 4 - display "job_mfront_sparse_nthreads_dom" - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - } - - label { - position 0 +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_automatic_gr - visible "*job_option mfront_sparse_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_user_gr - visible "*job_option mfront_sparse_multi_threading_ddm:user" - } -} -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - - - -#-------------------------------------------------------------------------------------------------- -group job_solver_gpu_gr { - - toggle { - position 0 0 - size 30 4 - text "USE \{GPU(s)}" - toggle "*job_option solver_use_gpu:on" - true_command "*job_option solver_use_gpu:on" - false_command "*job_option solver_use_gpu:off" - help job_solver_gpu - } - frame{ - position 0 +4 - size 28 4 - group{ - layout hbox - - label { - position 0 0 - size 16 4 - text "\{GPU} SELECTION" - border_width 1 - border_color black - visible "*job_option solver_use_gpu:on" - } - - roller { - position +16 = - size 12 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - rollers "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - visible "*job_option solver_use_gpu:on" - help job_solver_gpu - } - - text { - position +12 = - size 12 4 - display job_solver_gpus - command "*clear_job_solver_gpus *job_solver_gpus" - visible "and(*job_option solver_use_gpu:on,*job_option solver_gpus:user)" - } - spacer { - stretch 1 - } - } - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option pardiso_multi_threading:on" - true_command "*job_option pardiso_multi_threading:on" - false_command "*job_option pardiso_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option pardiso_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option pardiso_multi_threading:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position = +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_pardiso_multi_threads_ddm_automatic_gr - visible "*job_option pardiso_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_pardiso_multi_threads_ddm_user_gr - visible "*job_option pardiso_multi_threading_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_it_ext_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option it_ext_multi_threading:on" - true_command "*job_option it_ext_multi_threading:on" - false_command "*job_option it_ext_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option it_ext_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option it_ext_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_gr { - - frame{ - position 0 +4 - size 40 4 - group{ - layout hbox - label{ - position 0 0 - size 8 4 - text "SETUP" - help job_run_ddm_setup - } - oneonly { - position +12 = - size 12 4 - text "SINGLE MACHINE" - oneonly "*job_option parallel_setup:single" - command "*job_option parallel_setup:single" - help job_run_ddm_setup - } - oneonly { - position +8 = - size 12 4 - text "NETWORK" - oneonly "*job_option parallel_setup:network" - command "*job_option parallel_setup:network" - help job_run_ddm_setup - } - - spacer { - stretch 1 - } - } - } - - - frame { - position +1 +5 - size 40 16 - group job_parallel_env_network_gr - visible "*job_option parallel_setup:network" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_gr { - - button { - position 0 0 - size 28 4 - text "HOST FILE" - browser host_file_browser - settext $host_file_browser_label "SELECT HOST FILE" - set $host_file_browser_command "*job_host_file" - help job_host_file - } - - button { - position +28 = - size 8 4 - text "EDIT" - command "*job_edit_host_file" - help job_edit_host_file - visible job_host_file - } - - button { - position +8 = - size 8 4 - text "CLEAR" - command "*job_clear_host_file" - help job_clear_host_file - visible job_host_file - } - - display { - position 0 +4 - size 44 4 - display job_host_file - } - - frame { - position 0 +5 - size 44 9 - group job_parallel_env_network_ddm_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_ddm_gr { - - toggle { - position 0 0 - size 22 4 - text "COPY INPUT FILE" - toggle "*job_option copy_input_file:on" - true_command "*job_option copy_input_file:on" - false_command "*job_option copy_input_file:off" - help job_host_copy_inputfile - } - - toggle { - position +23 = - size 21 4 - text "COPY POST FILE" - toggle "*job_option copy_post_file:on" - true_command "*job_option copy_post_file:on" - false_command "*job_option copy_post_file:off" - help job_host_copy_inputfile - } - - label { - position 0 +5 - size 10 4 - text "HOSTS" - border_width 1 - border_color black - visible job_usersub_file - } - - roller { - position +10 = - size 18 4 - nvalues 2 - texts "COMPATIBLE" - "INCOMPATIBLE" - roller "job_option network_hosts" - commands "*job_option network_hosts:compatible" - "*job_option network_hosts:incompatible" - help job_host_comp - visible job_usersub_file - } -} - - -#endif diff --git a/installation/mods_MarcMentat/2018.1/Mentat_menus/job_run.ms.original b/installation/mods_MarcMentat/2018.1/Mentat_menus/job_run.ms.original deleted file mode 100644 index 582632dc9..000000000 --- a/installation/mods_MarcMentat/2018.1/Mentat_menus/job_run.ms.original +++ /dev/null @@ -1,2568 +0,0 @@ -#ifndef AUTOFORGE -popmenu job_title_pm file jobs.ms -popdown job_title_ok file jobs.ms - -group user_domains_gr file domain_decomposition.ms -group user_domains_generate_gr file domain_decomposition.ms -group user_domains_tail_gr file domain_decomposition.ms -group matrix_solver_gr file job_common.ms -popmenu ddm_options file job_common.ms - -browser edit_browser file file.ms -browser directory_browser file file.ms -screen domains file domain_decomposition.ms - - - - browser usersub_file_browser { - position 0 0 - size 82 72 - text "$usersub_file_browser_label" ($usersub_file_browser_label) - filter "*.f *.F *.f90 *.F90" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$usersub_file_browser_command" ($usersub_file_browser_command) - } - - - - browser host_file_browser { - position 0 0 - size 82 72 - text "$host_file_browser_label" ($host_file_browser_label) - filter "*" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$host_file_browser_command" ($host_file_browser_command) - } - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_popmenu { - - text "RUN JOB" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - button { - position 1 9 - size 24 4 - text "USER SUBROUTINE FILE" - browser usersub_file_browser - settext $usersub_file_browser_label "SELECT USER SUBROUTINE FILE" - set $usersub_file_browser_command "*job_usersub_file" - help job_usersub_file - } - - toggle { - position +26 = - size 22 4 - text "SELECTED USER SUBS" - toggle job_usersubs - help job_run_seluser - visible job_usersubs - popmenu job_usersub_pm - } - - display { - position 1 +4 - size 50 4 - display job_usersub_file - } - - button { - position 1 +4 - size 12 4 - text "EDIT" - command "*job_edit_usersub_file" - visible job_usersub_file - } - - button { - position +12 = - size 12 4 - text "CLEAR" - command "*job_clear_usersub_file" - visible job_usersub_file - } - - roller { - position +12 = - size 26 4 - nvalues 3 - texts "COMPILE / NO SAVE" - "COMPILE AND SAVE" - "RUN SAVED EXECUTABLE" - help job_run_compile - roller "job_option user_source" - visible job_usersub_file - commands "*job_option user_source:compile_nosave" - "*job_option user_source:compile_save" - "*job_option user_source:run_saved" - } - - button { - position 1 +6 - size 24 4 - text "SOLVER/PARALLELIZATION" - help job_run_parallel - popmenu job_run_parallelization_pm - set $popname2 "job_run_parallelization_pm" - } - frame { - position 1 +4 - size 48 16 - border_width 1 - border_color black - - group{ - layout hbox - frame { - position 0 0 - size 24 16 - group { - layout vbox - - display { - position 0 0 - size 24 4 - display job_solver_solution - } - - display { - position = +4 - size 24 4 - display job_solver_type - } - spacer { - stretch 1 - } - - } - } - - frame { - position +22 = - size 24 16 - border_width 1 - border_color black - - group { - #layout vbox - display { - position = +4 - size 24 4 - display job_ddm_domains - } - - display { - position = +4 - size 24 4 - display job_assem_recov_nthreads - } - - display { - position = +4 - size 24 4 - display job_solver_procs - visible solver_allows_multi_procs - } - - display { - position = = - size 24 4 - display job_solver_threads - visible "and(solver_allows_multi_threads,\ - not(and(job_solver_mfront_sparse,\ - *job_option parallel:on)))" - } - - display { - position = +4 - size 24 4 - display job_solver_gpu - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } - } - } - } - } - - button { - position 1 +18 - size 8 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - -# see also job_common.ms -# see also the ADVANCED JOB SUBMISSION popmenu in this file - - label { - position +10 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - button { - position +20 = - size 13 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position 1 +6 - size 16 6 - text "SUBMIT (1)" - command "*submit_job 1 *monitor_job" - } - - button { - position +16 = - size 34 6 - text "ADVANCED JOB SUBMISSION" - popmenu job_submit_adv_pm - } - - button { - position 1 +6 - size 16 6 - text "UPDATE" - command "*update_job" - } - - button { - position +16 = - size 16 6 - text "MONITOR" - command "*monitor_job" - } - - button { - position +16 = - size 18 6 - text "KILL" - command "*kill_job *monitor_job" - } - - label { - position 1 +7 - size 32 4 - text "STATUS" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_status" - } - - label { - position -32 +4 - size 32 4 - text "CURRENT INCREMENT (CYCLE)" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_increment" - } - - label { - position -32 +4 - size 32 4 - text "SINGULARITY RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_singularity_ratio" - } - - label { - position -32 +4 - size 32 4 - text "CONVERGENCE RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_convergence_ratio" - } - - label { - position 1 +4 - size 32 4 - text "ANALYSIS TIME" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_analysis_time" - } - - label { - position -32 +4 - size 32 4 - text "WALL TIME" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_time" - } - - frame { - position 1 +4 - size 50 8 - - group { - - frame { - position 0 0 - size 50 8 - text "TOTAL" - border_width 1 - border_color black - group { - - label { - position +6 = - size 13 4 - text "CYCLES" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_cycles" - border_width 1 - border_color black - } - - label { - position -13 +4 - size 13 4 - text "SEPARATIONS" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_separations" - border_width 1 - border_color black - } - - label { - position +10 -4 - size 11 4 - text "CUT BACKS" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_cut_backs" - border_width 1 - border_color black - } - - label { - position -11 +4 - size 11 4 - text "REMESHES" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_remeshes" - border_width 1 - border_color black - } - } - } - } - } - - label { - position 1 +8 - size 19 4 - text "EXIT NUMBER" - border_width 1 - border_color black - } - - integer { - position +19 = - size 10 4 - display "job_exit" - } - - button { - position +10 = - size 21 4 - text "EXIT MESSAGE" - popmenu job_exit_msg_pm - help exit_message - } - - label { - position 1 +6 - size 7 4 - text "EDIT" - border_width 1 - border_color black - } - - button { - position +7 = - size 12 4 - text "OUTPUT FILE" - command "*job_edit_output" - } - - button { - position +12 = - size 9 4 - text "LOG FILE" - command "*job_edit_log_file" - } - - button { - position +9 = - size 12 4 - text "STATUS FILE" - command "*job_edit_status_file" - } - - button { - position +12 = - size 10 4 - text "ANY FILE" - settext $edit_browser_label "EDIT FILE" - set $edit_browser_command "*edit_file" - browser edit_browser - help edit_file - } - - popdown { - position 1 +6 - size 32 4 - text "OPEN POST FILE (MODEL PLOT RESULTS MENU)" - command "@popdown(job_properties_pm) @main(results) @popup(modelplot_pm) *post_open_default" - } - - button { - position 1 +6 - size 12 8 - text "RESET" - command "*job_submit_reset" - } - - popdown { - position +38 = - size 12 8 - text "OK" - } - } - - window job_run_wi { - parent mentat - origin 35 1 - size 52 115 - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_usersub_pm { - - text "CURRENTLY SELECTED USER SUBROUTINES" - - group { - - - display { - position 1 +5 - size 64 86 - display "job_usersubs" - } - - popdown { - position 27 +88 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 66 102 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_submit_adv_pm { - - text "ADVANCED JOB SUBMISSION" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - label { - position 1 9 - size 19 4 - text "INITIAL ALLOCATION" - border_width 1 - border_color black - } - label { - position +19 = - size 15 4 - text "GENERAL MEMORY" - help job_param_general_init_allocation - } - text { - position +15 = - size 10 4 - display "job_param_value_general_init_allocation" - command "*job_param general_init_allocation" - help job_param_general_init_allocation - } - - label { - position +10 = - size 4 4 - text "MB" - border_width 1 - border_color black - } - - toggle { - position 1 +5 - size 32 4 - text "OUT-OF-CORE ELEMENT STORAGE" - help job_param_elsto - toggle "*job_option elsto:on" - true_command "*job_option elsto:on" - false_command "*job_option elsto:off" - } - - toggle { - position 1 +4 - size 32 4 - text "OUT-OF-CORE INCREMENTAL BACKUP" - help job_param_inc_backup_storage - toggle "*job_option inc_backup_storage:out_of_core" - true_command "*job_option inc_backup_storage:out_of_core" - false_command "*job_option inc_backup_storage:in_core" - } - - toggle { - position +34 = - size 14 4 - text "CHECK SIZES" - help job_run_check - toggle "*job_option check:on" - true_command "*job_option check:on" - false_command "*job_option check:off" - } - - frame { - position 1 +6 - size 48 12 - text "MARC INPUT FILE" - border_width 1 - border_color black - - group { - - label { - position 0 4 - size 9 4 - text "VERSION" - border_width 1 - border_color black - } - - roller { - position +9 = - size 14 4 - nvalues 26 - nvisible 26 - texts "DEFAULT" -#if 0 - "2018.1" -#endif - "2018" - "2017.1" - "2017" - "2016" - "2015" - "2014.2" - "2014.1" - "2014" - "2013.1" - "2013" - "2012" - "2011" - "2010.2" - "2010" - "2008" - "2007" - "2005R3" - "2005" - "2003" - "2001" - "2000" -#if 0 - "8" -#endif - "K7" - "K6.2" - "K5" - "K4" - help job_param_version - rollers "job_input_version_default" -#if 0 - "job_input_version_2018.1" -#endif - "job_input_version_2018" - "job_input_version_2017.1" - "job_input_version_2017" - "job_input_version_2016" - "job_input_version_2015" - "job_input_version_2014.2" - "job_input_version_2014.1" - "job_input_version_2014" - "job_input_version_2013.1" - "job_input_version_2013" - "job_input_version_2012" - "job_input_version_2011" - "job_input_version_2010.2" - "job_input_version_2010" - "job_input_version_2008" - "job_input_version_2007" - "job_input_version_2005r3" - "job_input_version_2005" - "job_input_version_2003" - "job_input_version_2001" - "job_input_version_2000" -#if 0 - "job_input_version_8" -#endif - "job_input_version_k7" - "job_input_version_k6" - "job_input_version_k5" - "job_input_version_k4" - commands "*job_option version:default" -#if 0 - "*job_option version:2018.1" -#endif - "*job_option version:2018" - "*job_option version:2017.1" - "*job_option version:2017" - "*job_option version:2016" - "*job_option version:2015" - "*job_option version:2014.2" - "*job_option version:2014.1" - "*job_option version:2014" - "*job_option version:2013.1" - "*job_option version:2013" - "*job_option version:2012" - "*job_option version:2011" - "*job_option version:2010.2" - "*job_option version:2010" - "*job_option version:2008" - "*job_option version:2007" - "*job_option version:2005r3" - "*job_option version:2005" - "*job_option version:2003" - "*job_option version:2001" - "*job_option version:2000" -#if 0 - "*job_option version:8" -#endif - "*job_option version:k7" - "*job_option version:k6" - "*job_option version:k5" - "*job_option version:k4" - visibles "job_allows_input_version_default" -#if 0 - "job_allows_input_version_2018.1" -#endif - "job_allows_input_version_2018" - "job_allows_input_version_2017.1" - "job_allows_input_version_2017" - "job_allows_input_version_2016" - "job_allows_input_version_2015" - "job_allows_input_version_2014.2" - "job_allows_input_version_2014.1" - "job_allows_input_version_2014" - "job_allows_input_version_2013.1" - "job_allows_input_version_2013" - "job_allows_input_version_2012" - "job_allows_input_version_2011" - "job_allows_input_version_2010.2" - "job_allows_input_version_2010" - "job_allows_input_version_2008" - "job_allows_input_version_2007" - "job_allows_input_version_2005r3" - "job_allows_input_version_2005" - "job_allows_input_version_2003" - "job_allows_input_version_2001" - "job_allows_input_version_2000" -#if 0 - "job_allows_input_version_8" -#endif - "job_allows_input_version_k7" - "job_allows_input_version_k6" - "job_allows_input_version_k5" - "job_allows_input_version_k4" - } - -# see also job_common.ms -# see also the RUN JOB popmenu in this file - - label { - position +14 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - toggle { - position 0 +4 - size 24 4 - text "EXTENDED PRECISION" - help job_run_precision - toggle "*job_option inp_file_prec:extended" - true_command "*job_option inp_file_prec:extended" - false_command "*job_option inp_file_prec:normal" - } - toggle { - position +24 = - size 24 4 - text "INCLUDE UNUSED TABLES" - toggle "*job_option input_file_tables:all" - true_command "*job_option input_file_tables:all" - false_command "*job_option input_file_tables:used" - } - } - } - - button { - position 1 +14 - size 24 4 - text "SCRATCH DIRECTORY" - settext $directory_browser_label "JOB SCRATCH DIRECTORY" - set $directory_browser_command "*job_scratch_directory" - browser directory_browser - help job_scratch_directory - } - - button { - position +24 = - size 24 4 - text "CLEAR" - command "*job_clear_scratch_directory" - visible job_scratch_directory - } - - text { - position 1 +4 - size 48 4 - display job_scratch_dir - command "*job_scratch_directory" - } - -#ifdef DCOM - toggle { - position 1 +6 - size 8 4 - text "\{DCOM}" - toggle "*job_option dcom:on" - help job_run_dcom - true_command "*job_option dcom:on" - false_command "*job_option dcom:off" - visible win32_available - } - - button { - position +8 = - size 12 4 - text "HOSTNAME" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } - - text job_dcom_hostname { - position +12 = - size 28 4 - display "job_dcom_hostname" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } -#endif - - button { - position 1 +6 - size 24 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - - button { - position +24 = - size 24 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position +4 +6 - size 20 4 - text "WRITE INPUT FILE" - command "*job_write_input" - } - - button { - position = +4 - size 20 4 - text "EDIT INPUT FILE" - command "*job_edit_input" - } - - popdown { - position 1 +5 - size 20 6 - text "SUBMIT 1" - command "*submit_job 1 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 1" - command "*execute_job 1 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 2" - command "*submit_job 2 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 2" - command "*execute_job 2 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 3" - command "*submit_job 3 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 3" - command "*execute_job 3 *monitor_job" - } - - popdown { - position 19 +8 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 -#ifdef DCOM - size 50 100 -#else - size 50 94 -#endif - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_exit_msg_pm { - - text "EXIT MESSAGE" - - group { - - - - text { - position 1 5 - size 84 74 - multiline - readonly - display "job_exit_msg" - } - - popdown { - position 37 +76 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 86 90 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_parallelization_pm { - - text "SOLVER/PARALLELIZATION" - - group { - layout vbox - frame { - position 0 0 - size 42 8 - group { - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 36 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 36 4 - display job_class_label - } - } - } - frame { - position 0 8 - size 42 20 - group job_ddm_gr - text "DOMAIN DECOMPOSITION" - border_width 1 - border_color black - } - - frame { - position 0 +20 - size 42 13 - group job_assem_recov_gr - text "ASSEMBLY AND RECOVERY" - border_width 1 - border_color black - } - - frame { - position 0 +14 - size 42 31 - group job_parallel_matrix_solver_gr - text "MATRIX SOLVER" - border_width 1 - border_color black - } - - frame { - position 0 +32 - size 42 28 - group job_parallel_env_gr - text "PARALLELIZATION ENVIRONMENT" - border_width 1 - border_color black - visible "or(*job_option parallel:on, \ - solver_multi_procs)" - } - frame { - position 15 +30 - size 42 8 - group { - layout hbox - - spacer { - stretch 1 - } - popdown { - position 15 0 - size 12 8 - text "OK" - } - spacer { - stretch 1 - } - } - } - - spacer { - spacing 2 - stretch 1 - } - } - - window { - parent mentat - origin 38 1 - size 60 119 - background_color body - border_width 1 - border_color border - buffering single - } - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_gr { - - toggle { - position 1 4 - size 42 4 - text "USE \{DDM}" - toggle "*job_option parallel:on" - help job_run_ddm_use - true_command "*job_option parallel:on" - false_command "*job_option parallel:off" - active "and(not(job_solver_it_ext),\ - not(job_solver_mixed_direct_iterative))" - } - - frame { - position = +5 - size 42 4 - group job_ddm_use_gr - visible "*job_option parallel:on" - } -} - -group job_ddm_use_gr { - layout vbox - frame{ - position 0 0 - size 30 4 - group { - layout hbox - label { - position 0 0 - size 12 4 - text "DECOMPOSITION IN" - help job_run_ddm_generator - } - oneonly{ - position +12 = - size 8 4 - text "MARC" - oneonly "*job_option ddm_generator:fea_solver" - command "*job_option ddm_generator:fea_solver" - help job_run_ddm_generator - } - oneonly{ - position +12 = - size 8 4 - text "MENTAT" - oneonly "*job_option ddm_generator:preprocessor" - command "*job_option ddm_generator:preprocessor" - help job_run_ddm_generator - } - } - } - - frame { - position 0 +5 - size 44 8 - group job_ddm_fea_solver_gr - visible "*job_option ddm_generator:fea_solver" - } - - frame { - position = = - size 44 8 - group job_ddm_preprocessor_gr - visible "*job_option ddm_generator:preprocessor" - } - - frame{ - position 0 +5 - size 40 4 - group{ - layout hbox - text { - position 0 0 - size 22 4 - text "Single Input File" - readonly - visible "*job_option ddm_generator:fea_solver" - } - - roller { - position = = - size 22 4 - nvalues 2 - texts "MULTIPLE INPUT FILES" - "SINGLE INPUT FILE" - roller "job_option ddm_single_input" - commands "*job_option ddm_single_input:off" - "*job_option ddm_single_input:on" - visible "*job_option ddm_generator:preprocessor" - help job_run_ddm_single_input - } - - roller { - position +23 = - size 21 4 - nvalues 2 - texts "MULTIPLE POST FILES" - "SINGLE POST FILE" - roller "job_option ddm_single_post" - commands "*job_option ddm_single_post:off" - "*job_option ddm_single_post:on" - help job_run_ddm_single_post - } - } - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_fea_solver_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - help job_param - } - - text { - position +10 = - size 4 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 0 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - button { - position +18 = - size 12 4 - text "ADV. SETTINGS" - popmenu job_ddm_fea_solver_pm - } -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_ddm_fea_solver_pm { - - text "JOB PARALLELIZATION" - - group { - units 32 120 - - - label { - position 0 5 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - frame { - - position 0 +9 - size 32 76 - text "ADVANCED DECOMPOSITION IN MARC" - border_width 1 - border_color black - - group { - - label { - position 1 4 - size 16 4 - text "# DOMAINS" - help job_param - } - - text { - position +16 = - size 14 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 1 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 23 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - frame { - position 1 +5 - size 30 20 - group job_ddm_direction_gr - visible "or(*job_option ddm_method:vector, \ - *job_option ddm_method:radial, \ - *job_option ddm_method:angular)" - } - - toggle { - position 1 +21 - size 30 4 - text "DOMAIN ISLAND REMOVAL" - toggle "*job_option ddm_island_removal:on" - true_command "*job_option ddm_island_removal:on" - false_command "*job_option ddm_island_removal:off" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "GRAPH" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "COARSE" - "FINE" - help ddm_decomp_coarse_graph - rollers "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - commands "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "QUADRATIC ELEMENTS" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "GENUINE" - "LINEARIZED" - help job_run_ddm_decomp_linearized - rollers "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - commands "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - } - - label { - position 1 +5 - size 15 4 - text "ELEMENT WEIGHT FACTOR" - help job_param - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_elem_weight_factor" - command "*job_param ddm_elem_weight_factor" - help job_run_ddm_decomp_element_weight_factor - } - - toggle { - position 1 +5 - size 30 4 - text "DETECT CONTACT" - toggle "*job_option ddm_detect_contact:on" - true_command "*job_option ddm_detect_contact:on" - false_command "*job_option ddm_detect_contact:off" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - help job_run_ddm_decomp_detect_contact - } - - label { - position = +5 - size 15 4 - text "CONTACT TOLERANCE" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - command "*set_ddm_contact_tolerance" - display "job_param_value_ddm_contact_tolerance" - command "*job_param ddm_contact_tolerance" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_tolerance - } - - label { - position -15 +4 - size 15 4 - text "CONTACT CONSTR FACTOR" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_contact_constr_factor" - command "*job_param ddm_contact_constr_factor" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_constraint_factor - } - } - } - - popdown { - position 0 +77 - size 32 8 - text "OK" - } - } - mode permanent -} # job_ddm_fea_solver_pm - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_direction_gr { - - button { - position 0 0 - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "*job_option ddm_method:vector" - } - - button { - position = = - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "not(*job_option ddm_method:vector)" - } - - button { - position +15 = - size 15 4 - text "FROM / TO" - command "*job_vector_from_to ddm_sort_direction_x" - } - - text { - position -15 +4 - size 10 4 - command "*job_param ddm_sort_direction_x" - display "job_param_value_ddm_sort_direction_x" - help ddm_job_decomp_user_direction_x - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_y" - display "job_param_value_ddm_sort_direction_y" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_z" - display "job_param_value_ddm_sort_direction_z" - } - - frame { - position 0 +4 - size 30 8 - group job_ddm_sort_point_gr - visible "not(*job_option ddm_method:vector)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_sort_point_gr { - - label { - position 0 0 - size 14 4 - border_width 1 - border_color black - text "POINT ON AXIS" - } - - roller { - position +14 = - size 10 4 - nvalues 2 - texts "DEFAULT" - "USER" - roller "job_option ddm_sort_point" - commands "*job_option ddm_sort_point:default" - "*job_option ddm_sort_point:user" - } - - button { - position +10 = - size 6 4 - text "SET" - command "*job_position ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position 0 +4 - size 10 4 - command "*job_param ddm_sort_point_x" - display "job_param_value_ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_y" - display "job_param_value_ddm_sort_point_y" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_z" - display "job_param_value_ddm_sort_point_z" - visible "*job_option ddm_sort_point:user" - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_preprocessor_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - border_width 1 - border_color black - } - - integer { - position +10 = - size 4 4 - display valid_domains - } - - button { - position 0 +4 - size 30 4 - text "USER DOMAINS" - popmenu domains_pm - help job_run_ddm_user_domains - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_assem_recov_gr { - - toggle { - position 1 +4 - size 30 4 - text "MULTIPLE THREADS" - true_command "*job_option assem_recov_multi_threading:on" - false_command "*job_option assem_recov_multi_threading:off" - toggle "*job_option assem_recov_multi_threading:on" - } - - label { - position = +4 - size 12 4 - text "# THREADS" - visible "*job_option assem_recov_multi_threading:on" - } - - text { - position +12 = - size 4 4 - display "job_param_value_assem_recov_nthreads" - command "*job_param assem_recov_nthreads" - visible "*job_option assem_recov_multi_threading:on" - } - - label { - position +4 = - size 10 4 - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - } - - display { - position +12 = - size 4 4 - display "job_assem_recov_nthreads_dom" - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - } - spacer{ - stretch 2 - } - -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_matrix_solver_gr { - layout vbox - frame { - position 1 0 - size 36 31 - group { - layout hbox - label { - position 3 4 - size 12 4 - text "SOLUTION" - border_width 1 - border_color black - } - oneonly { - position +12 = - size 12 4 - text "SYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_off" - command "*job_option solver_nonsym:off" - } - oneonly { - position +12 = - size 12 4 - text "NONSYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_on" - command "*job_option solver_nonsym:on" - } - spacer { - stretch 1 - } - } - } - - frame { - position 1 +5 - size 42 23 - group matrix_solver_gr - help job_param_solver - } - - frame { - position +1 = - size 42 4 - group job_run_solver_ddm_opts_gr - visible "*job_option parallel:on" - } - - frame { - position 1 +23 - size 42 8 - group job_solver_multi_procs_gr - visible solver_allows_multi_procs - } - - frame { - position = = - size 42 8 - group job_solver_multi_threads_gr - visible solver_allows_multi_threads - } - - frame { - position 1 +9 - size 42 8 - group job_solver_gpu_gr - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_run_solver_ddm_opts_gr { - - button { - position 0 0 - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options -# see also job_common.ms! - visible "not(or(job_solver_it_sparse, \ - job_solver_it_ext, \ - job_solver_mixed_direct_iterative, \ - job_solver_pardiso,\ - job_solver_mumps))" - } - button { - position = = - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options_mumps - visible "job_solver_mumps" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_gr { - frame { - position 0 0 - size 42 8 - group job_solver_multi_procs_parallel_off_gr - visible "*job_option parallel:off" - } - - frame { - position = = - size 42 8 - group job_solver_multi_procs_parallel_on_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - true_command "*job_option nsolver_procs_serial:on" - false_command "*job_option nsolver_procs_serial:off" - toggle "*job_option nsolver_procs_serial:on" - help job_run_multithreading - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - visible "*job_option nsolver_procs_serial:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - visible "*job_option nsolver_procs_serial:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - border_width 1 - border_color black - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - help job_run_multithreading - rollers "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_nsolver_procs_ddm_automatic_gr - visible "*job_option nsolver_procs_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_nsolver_procs_ddm_user_gr - visible "*job_option nsolver_procs_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - } -} - -group job_solver_multi_threads_gr { - frame { - position 0 0 - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_off_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:off)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_on_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:on)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_pardiso_parallel_off_gr - visible "and(job_solver_pardiso,*job_option parallel:off)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_pardiso_parallel_on_gr - visible "and(job_solver_pardiso,*job_option parallel:on)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_it_ext_off_gr - visible "and(job_solver_it_ext,*job_option parallel:off)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option mfront_sparse_multi_threading:on" - true_command "*job_option mfront_sparse_multi_threading:on" - false_command "*job_option mfront_sparse_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option mfront_sparse_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option mfront_sparse_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +30 0 - size 12 4 - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - } - - display { - position +12 0 - size 4 4 - display "job_mfront_sparse_nthreads_dom" - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - } - - label { - position 0 +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_automatic_gr - visible "*job_option mfront_sparse_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_user_gr - visible "*job_option mfront_sparse_multi_threading_ddm:user" - } -} -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - - - -#-------------------------------------------------------------------------------------------------- -group job_solver_gpu_gr { - - toggle { - position 0 0 - size 30 4 - text "USE \{GPU(s)}" - toggle "*job_option solver_use_gpu:on" - true_command "*job_option solver_use_gpu:on" - false_command "*job_option solver_use_gpu:off" - help job_solver_gpu - } - frame{ - position 0 +4 - size 28 4 - group{ - layout hbox - - label { - position 0 0 - size 16 4 - text "\{GPU} SELECTION" - border_width 1 - border_color black - visible "*job_option solver_use_gpu:on" - } - - roller { - position +16 = - size 12 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - rollers "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - visible "*job_option solver_use_gpu:on" - help job_solver_gpu - } - - text { - position +12 = - size 12 4 - display job_solver_gpus - command "*clear_job_solver_gpus *job_solver_gpus" - visible "and(*job_option solver_use_gpu:on,*job_option solver_gpus:user)" - } - spacer { - stretch 1 - } - } - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option pardiso_multi_threading:on" - true_command "*job_option pardiso_multi_threading:on" - false_command "*job_option pardiso_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option pardiso_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option pardiso_multi_threading:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position = +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_pardiso_multi_threads_ddm_automatic_gr - visible "*job_option pardiso_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_pardiso_multi_threads_ddm_user_gr - visible "*job_option pardiso_multi_threading_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_it_ext_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option it_ext_multi_threading:on" - true_command "*job_option it_ext_multi_threading:on" - false_command "*job_option it_ext_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option it_ext_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option it_ext_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_gr { - - frame{ - position 0 +4 - size 40 4 - group{ - layout hbox - label{ - position 0 0 - size 8 4 - text "SETUP" - help job_run_ddm_setup - } - oneonly { - position +12 = - size 12 4 - text "SINGLE MACHINE" - oneonly "*job_option parallel_setup:single" - command "*job_option parallel_setup:single" - help job_run_ddm_setup - } - oneonly { - position +8 = - size 12 4 - text "NETWORK" - oneonly "*job_option parallel_setup:network" - command "*job_option parallel_setup:network" - help job_run_ddm_setup - } - - spacer { - stretch 1 - } - } - } - - - frame { - position +1 +5 - size 40 16 - group job_parallel_env_network_gr - visible "*job_option parallel_setup:network" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_gr { - - button { - position 0 0 - size 28 4 - text "HOST FILE" - browser host_file_browser - settext $host_file_browser_label "SELECT HOST FILE" - set $host_file_browser_command "*job_host_file" - help job_host_file - } - - button { - position +28 = - size 8 4 - text "EDIT" - command "*job_edit_host_file" - help job_edit_host_file - visible job_host_file - } - - button { - position +8 = - size 8 4 - text "CLEAR" - command "*job_clear_host_file" - help job_clear_host_file - visible job_host_file - } - - display { - position 0 +4 - size 44 4 - display job_host_file - } - - frame { - position 0 +5 - size 44 9 - group job_parallel_env_network_ddm_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_ddm_gr { - - toggle { - position 0 0 - size 22 4 - text "COPY INPUT FILE" - toggle "*job_option copy_input_file:on" - true_command "*job_option copy_input_file:on" - false_command "*job_option copy_input_file:off" - help job_host_copy_inputfile - } - - toggle { - position +23 = - size 21 4 - text "COPY POST FILE" - toggle "*job_option copy_post_file:on" - true_command "*job_option copy_post_file:on" - false_command "*job_option copy_post_file:off" - help job_host_copy_inputfile - } - - label { - position 0 +5 - size 10 4 - text "HOSTS" - border_width 1 - border_color black - visible job_usersub_file - } - - roller { - position +10 = - size 18 4 - nvalues 2 - texts "COMPATIBLE" - "INCOMPATIBLE" - roller "job_option network_hosts" - commands "*job_option network_hosts:compatible" - "*job_option network_hosts:incompatible" - help job_host_comp - visible job_usersub_file - } -} - - -#endif diff --git a/installation/mods_MarcMentat/2018/Marc_tools/comp_damask_hmp b/installation/mods_MarcMentat/2018/Marc_tools/comp_damask_hmp deleted file mode 100644 index 2e6f44b77..000000000 --- a/installation/mods_MarcMentat/2018/Marc_tools/comp_damask_hmp +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -usernoext=$user -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - -# add BLAS options for linking - BLAS="%BLAS%" - -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user on host `hostname`" -echo "program: $program" - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$usernoext.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $BLAS \ - $SYSLIBS || \ - { - echo "$0: link failed for $usernoext.o on host `hostname`" - exit 1 - } - /bin/rm $userobj - /bin/rm $DIRJOB/*.mod - /bin/rm $DIRJOB/*.smod diff --git a/installation/mods_MarcMentat/2018/Marc_tools/comp_damask_lmp b/installation/mods_MarcMentat/2018/Marc_tools/comp_damask_lmp deleted file mode 100644 index d908d68ed..000000000 --- a/installation/mods_MarcMentat/2018/Marc_tools/comp_damask_lmp +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -usernoext=$user -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - -# add BLAS options for linking - BLAS="%BLAS%" - -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user on host `hostname`" -echo "program: $program" - $DFORTRANLOWMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$usernoext.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $BLAS \ - $SYSLIBS || \ - { - echo "$0: link failed for $usernoext.o on host `hostname`" - exit 1 - } - /bin/rm $userobj - /bin/rm $DIRJOB/*.mod - /bin/rm $DIRJOB/*.smod diff --git a/installation/mods_MarcMentat/2018/Marc_tools/comp_damask_mp b/installation/mods_MarcMentat/2018/Marc_tools/comp_damask_mp deleted file mode 100644 index b31d84d48..000000000 --- a/installation/mods_MarcMentat/2018/Marc_tools/comp_damask_mp +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -usernoext=$user -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - -# add BLAS options for linking - BLAS="%BLAS%" - -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user on host `hostname`" -echo "program: $program" - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$usernoext.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $BLAS \ - $SYSLIBS || \ - { - echo "$0: link failed for $usernoext.o on host `hostname`" - exit 1 - } - /bin/rm $userobj - /bin/rm $DIRJOB/*.mod - /bin/rm $DIRJOB/*.smod diff --git a/installation/mods_MarcMentat/2018/Marc_tools/comp_user.original b/installation/mods_MarcMentat/2018/Marc_tools/comp_user.original deleted file mode 100644 index 8679bb041..000000000 --- a/installation/mods_MarcMentat/2018/Marc_tools/comp_user.original +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user.f on host `hostname`" -echo "program: $program" - $FORTRAN $user.f || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$user.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $SYSLIBS || \ - { - echo "$0: link failed for $user.o on host `hostname`" - exit 1 - } - /bin/rm $userobj diff --git a/installation/mods_MarcMentat/2018/Marc_tools/include_linux64 b/installation/mods_MarcMentat/2018/Marc_tools/include_linux64 deleted file mode 100644 index c99313a30..000000000 --- a/installation/mods_MarcMentat/2018/Marc_tools/include_linux64 +++ /dev/null @@ -1,804 +0,0 @@ -# -# General definitions for the Marc 2018.0 version -# -# EM64T -# -# Linux RedHat 7.1 / SuSE 11 SP4 -# -# 64 bit MPI version -# -# Intel(R) Fortran Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.2.174 Build 20170213 -# -# Intel(R) C Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.2.174 Build 20170213 -# -# To check the O/S level, type: -# uname -a -# -# Distributed parallel MPI libraries: -# 1) HP MPI 2.3 -# To check the mpi version, type: -# mpirun -version -# 2) Intel MPI 2017.1 -# To check the mpi version, type: -# mpiexec.hydra -version -# -# To check the Compiler level, type using the compiler -# installation path: -# ifort -V -# icc -V -# -# REMARKS : This file contains the definitions of variables used during -# compilation loading and use of the MARC programmes . The -# current machine type is identified by means of the variable -# MACHINE , defined below. -# -# -# MPI_ROOT: root directory in which mpi shared libraries, etc. are located -# DIRJOB : directory in which spawned jobs should look for Marc input -# MPI_ARCH: system architecture -# MPI_EPATH: path where executable resides -# -REVISION="VERSION, BUILD" -HOSTNAME=`hostname` - -# find available memory in Mbyte on the machine -# can be set explicitly -MEMLIMIT=`free -m | awk '/Mem:/ {print $2}'` - -# set _OEM_NASTRAN to 1 for MD Nastran build -# override _OEM_NASTRAN setting with MARC_MD_NASTRAN environment variable -_OEM_NASTRAN="${MARC_MD_NASTRAN:-0}" - -# uncomment the following line for an autoforge build -#AUTOFORGE=1 -AUTOFORGE=0 -export AUTOFORGE - -# integer size -if test "$MARC_INTEGER_SIZE" = "" ; then - INTEGER_PATH= -else - INTEGER_PATH=/$MARC_INTEGER_SIZE -fi - -INTELPATH="/opt/intel/compilers_and_libraries_2017/linux" - -# find the root directory of the compiler installation: -# - if ifort is found in $PATH, then the root directory is derived -# from the path to ifort -# - if ifort is not found in $PATH, the root directory is assumed -# to be $INTELPATH and the directory in which ifort is found is -# added to $PATH -FCOMPPATH=`which "$FCOMP" 2>/dev/null` -if test -n "$FCOMPPATH"; then - # derive the root directory from $FCOMPPATH - FCOMPROOT="${FCOMPPATH%/bin/intel64/$FCOMP}" - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT="${FCOMPPATH%/bin/$FCOMP}" - fi - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT= - fi -elif test -d "$INTELPATH"; then - # check for compiler in $INTELPATH - if test -d "$INTELPATH/bin/intel64" -a \ - -x "$INTELPATH/bin/intel64/$FCOMP" ; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin/intel64:$PATH" - elif test -d "$INTELPATH/bin" -a \ - -x "$INTELPATH/bin/$FCOMP"; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin:$PATH" - else - FCOMPROOT= - fi -else - FCOMPROOT= -fi - -# DAMASK uses the HDF5 compiler wrapper around the Intel compiler -H5FC="$(h5fc -shlib -show)" -HDF5_LIB=${H5FC//ifort/} -FCOMP="$H5FC -DDAMASK_HDF5" - -# AEM -if test "$MARCDLLOUTDIR" = ""; then - DLLOUTDIR="$MARC_LIB" -else - DLLOUTDIR="$MARCDLLOUTDIR" -fi - -# settings for MKL -if test "$IMKLDIR" = ""; then - MARC_MKL="$FCOMPROOT/mkl/lib/intel64" -else - MARC_MKL=$IMKLDIR/lib/intel64 -fi - -# -# settings for Metis -# -METIS="-I$METIS_SOURCE/include" -METISLIBS="$METISLIB_DIR/libmarcddm.a $METISLIB_DIR/libmarcmetis.a " - -# -# settings for MPI -# -# RCP and RSH are used for parallel network runs -# replace with similar commands like rsh if needed -RCP=/usr/bin/scp -RSH=/usr/bin/ssh -# - - -MPI_DEFAULT=intelmpi -MPI_OTHER=hpmpi - -MPITYPE=$MPI_DEFAULT - -if test $AUTOFORGE -then - if test $AUTOFORGE = 1 - then - MPITYPE=none - fi -fi - - -# overrule MPITYPE setting with environmental variable MARC_MPITYPE -if test $MARC_MPITYPE -then - MPITYPE=$MARC_MPITYPE -fi - -# always set MPITYPE to none for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - MPITYPE=none -fi - -# Edit following lines to build with GPGPU version of BCS Solver for -# NVIDIA platforms -#BCSGPUSOLVER=NONE -BCSGPUSOLVER=BCSGPU - -# Edit following lines to set the openssl library -if test "$OPENSSL" != "NONE" -then - OPENSSL_LIB="$MARC_LIB/libcrypto.a" -fi -OPENSSL_INCLUDE=-I"$MARC_OPENSSL/include/" - -# activate contact component build if flagged -AEM_DLL=0 -if test "$AEM_BUILD" = "ON" ; then - AEM_DLL=1 - LINK_MARC_DLL="-shared -fPIC" - EXT_DLL="so" - MPITYPE=none - MPI_OTHER= - BCSGPUSOLVER=NONE - MUMPSSOLVER=NONE - CASISOLVER=NONE -fi - -SOLVERFLAGS= -if test "$BCSGPUSOLVER" = BCSGPU -then - SOLVERFLAGS="$SOLVERFLAGS -DBCSGPU -DCUDA" - BCS_DIR=bcsgpusolver -else - BCS_DIR=bcssolver -fi -# -# settings for MPI -# -DDM= -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - FCOMPMPI=mpif90 - export MPI_ROOT=$MARC_HPMPI - export MPI_REMSH=$RSH - export MPI_F77=$FCOMP - ARCHITECTURE=linux_amd64 - DDM="-I$MPI_ROOT/include/64 -DDDM -DHPMPI" - MPI_CLEAN= - export MPI_EPATH=$MARC_BIN - export LD_LIBRARY_PATH=$MPI_ROOT/lib/$ARCHITECTURE:$MARC_LIB:$MARC_LIB_SHARED:$LD_LIBRARY_PATH - export MPIHPSPECIAL="-e MPI_FLAGS=E,T,y1" -# Below line is moved in run_marc file -# export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - export MPIHPSPECIAL="$MPIHPSPECIAL -e BINDIR=$MARC_BIN" - if test -n "$MSC_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e MSC_LICENSE_FILE=$MSC_LICENSE_FILE" - fi - if test -n "$LM_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LM_LICENSE_FILE=$LM_LICENSE_FILE" - fi - export MPIHPSPECIAL="$MPIHPSPECIAL -e MPI_LIC_CHECKER=$MPI_ROOT/bin/licensing/amd64_s8/lichk.x" - RUN_JOB2="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -f " - RUN_JOB1="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -w $MPIHPSPECIAL -np " - RUN_JOB0= - fi - if test $MPITYPE = intelmpi - then - INTELMPI_VERSION=HYDRA - FCOMPMPI=mpiifort - MPI_ROOT=$MARC_INTELMPI - DDM="-I${MPI_ROOT}/include -DDDM" - PATH=$MPI_ROOT/bin:$PATH - export PATH - LD_LIBRARY_PATH=$MPI_ROOT/lib:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - if test $INTELMPI_VERSION = HYDRA - then - RUN_JOB1="${MPI_ROOT}/bin/mpiexec.hydra -genvall -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec.hydra -genvall" - else - RUN_JOB1="${MPI_ROOT}/bin/mpiexec -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec -configfile " - fi - RUN_JOB0= - MPI_CLEAN= - MPI_EPATH=$MARC_BIN - MPIR_HOME=$MPI_ROOT - MPICH_F77=$FCOMP - MPICH_F77LINKER=$FCOMP - export MPI_ROOT MPI_EPATH MPIR_HOME MPICH_F77 MPICH_F77LINKER - I_MPI_PIN_DOMAIN=node - export I_MPI_PIN_DOMAIN - fi -else - MPI_ROOT=$MARC_DUMMYMPI - export MPI_ROOT=$MARC_DUMMYMPI - DDM="-I$MPI_ROOT/include" -fi - -# -# variables for the "maintain" script -# - -MACHINENAME=LINUX -MACHINE64BIT=yes -MACHINE=Linux_EM64T -DEV=/dev/tape -GETLOG="whoami" -CLEAR="clear" -MY_UNAME=`uname -a` - -# Edit following 2 lines to build with VKI Solver -#VKISOLVER=VKI -VKISOLVER=NONE - -# Edit following 2 lines to build with CASI Solver -CASISOLVER=CASI -if test "$MARC_CASISOLVER" = "NONE" ; then - CASISOLVER=NONE -fi -#CASISOLVER=NONE - -# Edit following 2 lines to build with MF2 Solver -MF2SOLVER=NONE -#MF2SOLVER=SERIAL -#MF2SOLVER=MF2PARALLEL - -# Edit following lines to build with Intel(c) Multithreaded solver (PARDISO) -#INTELSOLVER=NONE -INTELSOLVER=PARDISO - -# Edit following lines to build with MUMPS -if test "$MARC_INTEGER_SIZE" = "i4" ; then - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -else - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -fi - -# Edit following 2 lines to build MARC dynamic shared library -MARC_DLL=MARC_DLL -MARC_DLL=NONE - -# always set VKISOLVER, CASISOLVER, BCSGPUSOLVER, and MARC_DLL to NONE for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE - MARC_DLL=NONE -fi -if test "$AEM_DLL" -eq 1 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE -fi - -# -# define Fortran and C compile syntax -# -if test "$VKISOLVER" = VKI -then - SOLVERFLAGS="$SOLVERFLAGS -DVKI" -fi - -if test "$CASISOLVER" = CASI -then - SOLVERFLAGS="$SOLVERFLAGS -DCASI" -fi - -if test "$MF2SOLVER" = MF2PARALLEL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2PARALLEL" -fi -if test "$MF2SOLVER" = MF2SERIAL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2SERIAL" -fi - -if test "$INTELSOLVER" = PARDISO -then - SOLVERFLAGS="$SOLVERFLAGS -DPARDISO" -fi - -if test "$MUMPSSOLVER" = MUMPS -then - SOLVERFLAGS="$SOLVERFLAGS -DMUMPS" -fi - - -if test "$MARC_DLL" = MARC_DLL -then - SOLVERFLAGS="$SOLVERFLAGS -DMARC_DLL" -fi - -LINK_OPT= -DEBUG_OPT= -C_DEBUG_OPT= - -#Uncomment following line to build Marc in debuggable mode -MARCDEBUG= -#MARCDEBUG="ON" - -if test "$MARCDEBUG" = "ON" -then - LINK_OPT="-debug -traceback" - DEBUG_OPT="-debug -traceback" - C_DEBUG_OPT="-debug -traceback" -fi - - -MARCCHECK= -#MARCCHECK="ON" -if test "$MARCCHECK" = "ON" -then - DEBUG_OPT="$DEBUG_OPT -fpe0 -fp-stack-check -check all -ftrapuv " - C_DEBUG_OPT="$C_DEBUG_OPT -fp-stack-check -check-uninit -Wformat -ftrapuv " -fi - -MARCCODECOV= -#MARCCODECOV="ON" - -MARCCODEPROF= -#MARCCODEPROF="ON" - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - I8FFLAGS= - I8DEFINES= - I8CDEFINES= -else - I8FFLAGS="-i8 -integer-size 64" - I8DEFINES="-DI64 -DINT=8" - I8CDEFINES="-U_DOUBLE -D_SINGLE" -fi - -MTHREAD=OPENMP -if test "$MARC_OPENMP" = "NONE" ; then - MTHREAD=NONE -fi -#MTHREAD=NONE -if test "$_OEM_NASTRAN" -ne 0 -then -MTHREAD=NONE -fi -if test "$AEM_DLL" -eq 1 -then - MTHREAD=NONE - CASISOLVER=NONE - VKISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - BCSGPUSOLVER=NONE - OPENSSL_LIB= - MARC_DLL=NONE - METISLIBS= -fi - -OMP_COMPAT=NO -OMP_COMPAT=YES -if test "$MTHREAD" = "NONE" -then -OMP_COMPAT=NO -fi - -CDEFINES= -FDEFINES= - -if test "$_OEM_NASTRAN" -ne 0 -then - CDEFINES="$CDEFINES -D_OEM_NASTRAN" - FDEFINES="$FDEFINES -D_OEM_NASTRAN" -fi - -FDEFINES="$FDEFINES -D_IMPLICITNONE" - -if test "$_OEM_NASTRAN" -eq 0 -then - FDEFINES="$FDEFINES -DMKL -DOPENMP" -fi - -if test "$OMP_COMPAT" = "YES" -then - FDEFINES="$FDEFINES -DOMP_COMPAT" -fi - -# -D_MSCMARC -FDEFINES="$FDEFINES -D_MSCMARC $DEBUG_OPT $MARC_SIMUFACT" -CDEFINES="$CDEFINES -D_MSCMARC $C_DEBUG_OPT $I8CDEFINES" - -if test "$AEM_DLL" -eq 1 -then - FDEFINES="$FDEFINES -D_AEMNL -DAAA" - CDEFINES="$CDEFINES -D_AEMNL -DAAA" -fi - -CINCL="-I$MARC_SOURCE/mdsrc -I$MARC_SOURCE/csource $METIS" -if test "$_OEM_NASTRAN" -ne 0 -then - CINCL="$CINCL -I../../include" -fi - -CC_OPT= -if test "$MTHREAD" = "OPENMP" -then - CC_OPT=" $CC_OPT -qopenmp" -fi - -CC="icc -c $CC_OPT -O1 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCLOW="icc -c $CC_OPT -O0 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCHIGH="icc -c $CC_OPT -O3 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - -if test "$MARCDEBUG" = "ON" -then - CC="icc -c $CC_OPT -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCLOW="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCHIGH="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -fi - -LOAD_CC="icc $CC_OPT -O1 -DLinux -DLINUX -DLinux_intel" -CCT="$CC" -CCTLOW="$CCLOW" -CCTHIGH="$CCHIGH" - -#PROFILE="-Mprof=func" -#PROFILE="-Mprof=lines" -#PROFILE="-Mprof=func,mpi" -PROFILE= -#PROFILE="-init=snan,arrays -CB -traceback -fpe0 -fp-stack-check -check all -check uninit -ftrapuv" -if test "$MARCCODECOV" = "ON" -then -PROFILE="-prof-gen=srcpos" -fi -if test "$MARCCODEPROF" = "ON" -then -PROFILE=" $PROFILE -pg" -fi - -FORT_OPT="-c -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr -mp1 -WB -fp-model source" -if test "$MTHREAD" = "OPENMP" -then - FORT_OPT=" $FORT_OPT -qopenmp" - if test "$OMP_COMPAT" = "YES" - then - FORT_OPT=" $FORT_OPT -qopenmp-threadprivate=compat" - fi -else -# FORT_OPT=" $FORT_OPT -auto " - FORT_OPT=" $FORT_OPT -save -zero" -fi - -FORTLOW="$FCOMP $FORT_OPT $PROFILE -O0 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTRAN="$FCOMP $FORT_OPT $PROFILE -O1 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTNA="$FCOMP $FORT_OPT -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -# for compiling free form f90 files. high opt, integer(4) -FORTF90="$FCOMP -c -O3" - -# determine DAMASK version -if test -n "$DAMASK_USER"; then - DAMASKROOT=`dirname $DAMASK_USER`/.. - read DAMASKVERSION < $DAMASKROOT/VERSION - DAMASKVERSION="'"$DAMASKVERSION"'" -else - DAMASKVERSION="'N/A'" -fi - - -# DAMASK compiler calls: additional flags are in line 2 OpenMP flags in line 3 -DFORTLOWMP="$FCOMP -c -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2018 -DDAMASKVERSION=$DAMASKVERSION \ - -qopenmp -qopenmp-threadprivate=compat\ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -DFORTRANMP="$FCOMP -c -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2018 -DDAMASKVERSION=$DAMASKVERSION \ - -qopenmp -qopenmp-threadprivate=compat\ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -DFORTHIGHMP="$FCOMP -c -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2018 -DDAMASKVERSION=$DAMASKVERSION \ - -qopenmp -qopenmp-threadprivate=compat\ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - - -if test "$MARCDEBUG" = "ON" -then - FORTLOW="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTRAN="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTNA="$FCOMP $FORT_OPT -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -fi - - -FORTLOWT="$FORTLOW" -FORTRANT="$FORTRAN" -FORTHIGHT="$FORTHIGH" - -FORTRANMNF="$FCOMP -c $FDEFINES " -CCMNF="icc -c -O1 -DLinux -DLINUX -DLinux_intel -Dport2egcs -I$MARC_SOURCE/marctoadams/mnf/include -D_LARGEFILE64_SOURCE" - -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - LOAD="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - LOADT="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - fi -# Uncomment the following lines to turn on the tracer and commnet out the next 5 lines -# if test $MPITYPE = intelmpi -# then -# INCLUDEMPI="-I$MPI_ROOT/include -I$VT_ROOT/include" -# LOAD="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# LOADT="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# fi - if test $MPITYPE = intelmpi - then - LOAD="ifort $PROFILE $LINK_OPT -o " - LOADT="ifort $PROFILE $LINK_OPT -o " - fi -else - LOAD="$FCOMP $LINK_OPT -o " - LOADT="$FCOMP $LINK_OPT -o " -fi - -if test "$MARC_DLL" = MARC_DLL -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide -lpthread" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - -if test "$AEM_DLL" -eq 1 -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - - -XLIBS="-L/usr/X11/lib -lX11 " - -# -# define archive and ranlib syntax -# - -ARC="ar rvl" -ARD="ar dvl" -ARX="ar xl" -RAN="" - -# -# choose which libraries you want to use ( e.g. blas ) -# - -if test "$VKISOLVER" = VKI -then - VKISOLVERLIBS="$MARC_LIB/vkisolver.a" -else - VKISOLVERLIBS= -fi - -if test "$CASISOLVER" = CASI -then - CASISOLVERLIBS="$CASILIB_DIR/libmarccasi.a $CASILIB_DIR/libcasi.a" -else - CASISOLVERLIBS= -fi - -MF2SOLVERLIBS= -if test "$MF2SOLVER" = MF2PARALLEL -then - MF2SOLVERLIBS="$MARC_LIB/mf2parallel/libseq.a \ - $MARC_LIB/mf2parallel/libsym.a \ - $MARC_LIB/mf2parallel/libmet.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libnum.a \ - $MARC_LIB/mf2parallel/libutl.a \ - $MARC_LIB/mf2parallel/libr8.a \ - $MARC_LIB/mf2parallel/libz.a " -fi - -if test "$MUMPSSOLVER" = MUMPS -then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - if test $MPITYPE = none - then - MUMPSSOLVERLIBS2= - echo hello > /dev/null - fi - if test $MPITYPE = intelmpi - then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a " - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a " - fi - fi - if test $MPITYPE = hpmpi - then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a" - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a" - fi - fi -else - MUMPSSOLVERLIBS= - MUMPSSOLVERLIBS2= -fi - -if test "$BCSGPUSOLVER" = BCSGPU -then - BCSSOLVERLIBS="${BCSLIB_DIR}/bcsgpulib.a " - MARCCUDALIBS1="-L${BCSLIB_DIR}/cuda_dummy -lmarccuda " - MARCCUDALIBS2="-L${BCSLIB_DIR}/cuda -lmarccuda " - MARCCUDALIBS=$MARCCUDALIBS1 -else - BCSSOLVERLIBS="${MARC_LIB}/bcslib.a " -fi -if test "$AEM_DLL" -eq 1 -then - BCSSOLVERLIBS= -fi - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - MKLLIB="$MARC_MKL/libmkl_scalapack_lp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_lp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MARC_MKL/libmkl_blacs_intelmpi_lp64.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -else - MKLLIB="$MARC_MKL/libmkl_scalapack_ilp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_ilp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -fi - -SECLIBS="-L$MARC_LIB -llapi" - -SOLVERLIBS="${BCSSOLVERLIBS} ${VKISOLVERLIBS} ${CASISOLVERLIBS} ${MF2SOLVERLIBS} \ - $MKLLIB -L$MARC_MKL -liomp5 \ - $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/kdtree2.a $HDF5_LIB " - -SOLVERLIBS_DLL=${SOLVERLIBS} -if test "$AEM_DLL" -eq 1 -then -SOLVERLIBS_DLL="$MKLLIB -L$MARC_MKL -liomp5 $MARC_LIB/blas_src.a" -fi -MRCLIBS="$MARC_LIB/clib.a ${CASISOLVERLIBS}" -MRCLIBSPAR="$MARC_LIB/clib.a" -STUBS="$MARC_LIB/stubs.a " -MNFLIBS="$MARC_LIB/libmnf.a" -MDUSER="$MARC_LIB/md_user.a" -if test "X$MARC_SIMUFACT" != "X" -then - SFLIB="-L$SFMATDIR -lMBA_Grain $SFMATDIR/sfclib.a " -else - SFLIB=" " -fi - -OPENMP="-qopenmp" - -if test "$AEM_DLL" -eq 1 -then - LOAD_DLL=$LOAD - OPENMP= - LIBMNF= - OPENSSL=NONE -fi - -SYSLIBS=" $OPENMP -lpthread -cxxlib" - -# Uncomment the following lines to turn on the trace and comment out the next 4 lines -# if test $MPITYPE = intelmpi -# then -# SYSLIBS="-L${VT_ROOT}/lib -lVT -ldwarf -lelf -lm -lpthread \ -# -L${MPI_ROOT}/lib64 -lmpi -lmpiif -lmpigi -lrt" -# fi -if test $MPITYPE = intelmpi -then - SYSLIBS="-L${MPI_ROOT}/lib -lmpi_mt -lmpifort -lrt $OPENMP -threads -lpthread -cxxlib" -fi - - -SYSLIBSPAR=" " - -MARC_DLL_CODES="runmarc.f" - - -BLAS_SRC="dzero.f icopy.f izero.f" -if test "$_OEM_NASTRAN" -ne 0 -then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - BLAS_SRC="$BLAS_SRC dsctr.f zsctr.f dzasum.f daxpyi.f zaxpyi.f dgthr.f zgthr.f" - else - BLAS_SRC="ALL" - fi -fi - -LOW_OPT_CODES="are163.f contro.f ndext.f omarc.f omarca.f omarcb.f omarcc.f \ - omars.f fixbc.f triang.f bet049.f norst3.f eldata.f \ - elec*.f elct*.f fmeig.f oada00.f ogeig.f updtrbe2.f cycrota.f \ - cordef.f ogpk.f ogtan.f eldam.f formrbe3.f \ - inertie.f em_sso072.f cn_fol3d_qpatch6.f cosim_begin.f" -if test "$MARC_INTEGER_SIZE" = "i8" ; then - LOW_OPT_CODES="$LOW_OPT_CODES bbcseg.f" -fi - -HIGH_OPT_CODES="dpsmsa1.f dpsmsa2.f dpsmsa3.f dpsmsa4.f dpsmsa5.f dpsmsa6.f \ - dpsmsa7.f dpsmsa8.f dpsmsa9.f dpsmsa10.f dpsmsa11.f dpsmsa12.f \ - dpsmsa13.f dpsmsa14.f dpsmsa15.f dpsmsa16.f dpsmsah.f tpsmsah.f cn_qsort4_11.f " - - - -MAXNUM=1000000 diff --git a/installation/mods_MarcMentat/2018/Marc_tools/include_linux64.original b/installation/mods_MarcMentat/2018/Marc_tools/include_linux64.original deleted file mode 100644 index 10ccebe32..000000000 --- a/installation/mods_MarcMentat/2018/Marc_tools/include_linux64.original +++ /dev/null @@ -1,774 +0,0 @@ -# -# General definitions for the Marc 2018.0 version -# -# EM64T -# -# Linux RedHat 7.1 / SuSE 11 SP4 -# -# 64 bit MPI version -# -# Intel(R) Fortran Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.2.174 Build 20170213 -# -# Intel(R) C Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.2.174 Build 20170213 -# -# To check the O/S level, type: -# uname -a -# -# Distributed parallel MPI libraries: -# 1) HP MPI 2.3 -# To check the mpi version, type: -# mpirun -version -# 2) Intel MPI 2017.1 -# To check the mpi version, type: -# mpiexec.hydra -version -# -# To check the Compiler level, type using the compiler -# installation path: -# ifort -V -# icc -V -# -# REMARKS : This file contains the definitions of variables used during -# compilation loading and use of the MARC programmes . The -# current machine type is identified by means of the variable -# MACHINE , defined below. -# -# -# MPI_ROOT: root directory in which mpi shared libraries, etc. are located -# DIRJOB : directory in which spawned jobs should look for Marc input -# MPI_ARCH: system architecture -# MPI_EPATH: path where executable resides -# -REVISION="VERSION, BUILD" -HOSTNAME=`hostname` - -# find available memory in Mbyte on the machine -# can be set explicitly -MEMLIMIT=`free -m | awk '/Mem:/ {print $2}'` - -# set _OEM_NASTRAN to 1 for MD Nastran build -# override _OEM_NASTRAN setting with MARC_MD_NASTRAN environment variable -_OEM_NASTRAN="${MARC_MD_NASTRAN:-0}" - -# uncomment the following line for an autoforge build -#AUTOFORGE=1 -AUTOFORGE=0 -export AUTOFORGE - -# integer size -if test "$MARC_INTEGER_SIZE" = "" ; then - INTEGER_PATH= -else - INTEGER_PATH=/$MARC_INTEGER_SIZE -fi - -FCOMP=ifort -INTELPATH="/opt/intel/compilers_and_libraries_2017/linux" - -# find the root directory of the compiler installation: -# - if ifort is found in $PATH, then the root directory is derived -# from the path to ifort -# - if ifort is not found in $PATH, the root directory is assumed -# to be $INTELPATH and the directory in which ifort is found is -# added to $PATH -FCOMPPATH=`which "$FCOMP" 2>/dev/null` -if test -n "$FCOMPPATH"; then - # derive the root directory from $FCOMPPATH - FCOMPROOT="${FCOMPPATH%/bin/intel64/$FCOMP}" - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT="${FCOMPPATH%/bin/$FCOMP}" - fi - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT= - fi -elif test -d "$INTELPATH"; then - # check for compiler in $INTELPATH - if test -d "$INTELPATH/bin/intel64" -a \ - -x "$INTELPATH/bin/intel64/$FCOMP" ; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin/intel64:$PATH" - elif test -d "$INTELPATH/bin" -a \ - -x "$INTELPATH/bin/$FCOMP"; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin:$PATH" - else - FCOMPROOT= - fi -else - FCOMPROOT= -fi - -# AEM -if test "$MARCDLLOUTDIR" = ""; then - DLLOUTDIR="$MARC_LIB" -else - DLLOUTDIR="$MARCDLLOUTDIR" -fi - -# settings for MKL -if test "$IMKLDIR" = ""; then - MARC_MKL="$FCOMPROOT/mkl/lib/intel64" -else - MARC_MKL=$IMKLDIR/lib/intel64 -fi - -# -# settings for Metis -# -METIS="-I$METIS_SOURCE/include" -METISLIBS="$METISLIB_DIR/libmarcddm.a $METISLIB_DIR/libmarcmetis.a " - -# -# settings for MPI -# -# RCP and RSH are used for parallel network runs -# replace with similar commands like rsh if needed -RCP=/usr/bin/scp -RSH=/usr/bin/ssh -# - - -MPI_DEFAULT=intelmpi -MPI_OTHER=hpmpi - -MPITYPE=$MPI_DEFAULT - -if test $AUTOFORGE -then - if test $AUTOFORGE = 1 - then - MPITYPE=none - fi -fi - - -# overrule MPITYPE setting with environmental variable MARC_MPITYPE -if test $MARC_MPITYPE -then - MPITYPE=$MARC_MPITYPE -fi - -# always set MPITYPE to none for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - MPITYPE=none -fi - -# Edit following lines to build with GPGPU version of BCS Solver for -# NVIDIA platforms -#BCSGPUSOLVER=NONE -BCSGPUSOLVER=BCSGPU - -# Edit following lines to set the openssl library -if test "$OPENSSL" != "NONE" -then - OPENSSL_LIB="$MARC_LIB/libcrypto.a" -fi -OPENSSL_INCLUDE=-I"$MARC_OPENSSL/include/" - -# activate contact component build if flagged -AEM_DLL=0 -if test "$AEM_BUILD" = "ON" ; then - AEM_DLL=1 - LINK_MARC_DLL="-shared -fPIC" - EXT_DLL="so" - MPITYPE=none - MPI_OTHER= - BCSGPUSOLVER=NONE - MUMPSSOLVER=NONE - CASISOLVER=NONE -fi - -SOLVERFLAGS= -if test "$BCSGPUSOLVER" = BCSGPU -then - SOLVERFLAGS="$SOLVERFLAGS -DBCSGPU -DCUDA" - BCS_DIR=bcsgpusolver -else - BCS_DIR=bcssolver -fi -# -# settings for MPI -# -DDM= -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - FCOMPMPI=mpif90 - export MPI_ROOT=$MARC_HPMPI - export MPI_REMSH=$RSH - export MPI_F77=$FCOMP - ARCHITECTURE=linux_amd64 - DDM="-I$MPI_ROOT/include/64 -DDDM -DHPMPI" - MPI_CLEAN= - export MPI_EPATH=$MARC_BIN - export LD_LIBRARY_PATH=$MPI_ROOT/lib/$ARCHITECTURE:$MARC_LIB:$MARC_LIB_SHARED:$LD_LIBRARY_PATH - export MPIHPSPECIAL="-e MPI_FLAGS=E,T,y1" -# Below line is moved in run_marc file -# export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - export MPIHPSPECIAL="$MPIHPSPECIAL -e BINDIR=$MARC_BIN" - if test -n "$MSC_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e MSC_LICENSE_FILE=$MSC_LICENSE_FILE" - fi - if test -n "$LM_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LM_LICENSE_FILE=$LM_LICENSE_FILE" - fi - export MPIHPSPECIAL="$MPIHPSPECIAL -e MPI_LIC_CHECKER=$MPI_ROOT/bin/licensing/amd64_s8/lichk.x" - RUN_JOB2="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -f " - RUN_JOB1="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -w $MPIHPSPECIAL -np " - RUN_JOB0= - fi - if test $MPITYPE = intelmpi - then - INTELMPI_VERSION=HYDRA - FCOMPMPI=mpiifort - MPI_ROOT=$MARC_INTELMPI - DDM="-I${MPI_ROOT}/include -DDDM" - PATH=$MPI_ROOT/bin:$PATH - export PATH - LD_LIBRARY_PATH=$MPI_ROOT/lib:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - if test $INTELMPI_VERSION = HYDRA - then - RUN_JOB1="${MPI_ROOT}/bin/mpiexec.hydra -genvall -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec.hydra -genvall" - else - RUN_JOB1="${MPI_ROOT}/bin/mpiexec -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec -configfile " - fi - RUN_JOB0= - MPI_CLEAN= - MPI_EPATH=$MARC_BIN - MPIR_HOME=$MPI_ROOT - MPICH_F77=$FCOMP - MPICH_F77LINKER=$FCOMP - export MPI_ROOT MPI_EPATH MPIR_HOME MPICH_F77 MPICH_F77LINKER - I_MPI_PIN_DOMAIN=node - export I_MPI_PIN_DOMAIN - fi -else - MPI_ROOT=$MARC_DUMMYMPI - export MPI_ROOT=$MARC_DUMMYMPI - DDM="-I$MPI_ROOT/include" -fi - -# -# variables for the "maintain" script -# - -MACHINENAME=LINUX -MACHINE64BIT=yes -MACHINE=Linux_EM64T -DEV=/dev/tape -GETLOG="whoami" -CLEAR="clear" -MY_UNAME=`uname -a` - -# Edit following 2 lines to build with VKI Solver -#VKISOLVER=VKI -VKISOLVER=NONE - -# Edit following 2 lines to build with CASI Solver -CASISOLVER=CASI -if test "$MARC_CASISOLVER" = "NONE" ; then - CASISOLVER=NONE -fi -#CASISOLVER=NONE - -# Edit following 2 lines to build with MF2 Solver -MF2SOLVER=NONE -#MF2SOLVER=SERIAL -#MF2SOLVER=MF2PARALLEL - -# Edit following lines to build with Intel(c) Multithreaded solver (PARDISO) -#INTELSOLVER=NONE -INTELSOLVER=PARDISO - -# Edit following lines to build with MUMPS -if test "$MARC_INTEGER_SIZE" = "i4" ; then - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -else - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -fi - -# Edit following 2 lines to build MARC dynamic shared library -MARC_DLL=MARC_DLL -MARC_DLL=NONE - -# always set VKISOLVER, CASISOLVER, BCSGPUSOLVER, and MARC_DLL to NONE for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE - MARC_DLL=NONE -fi -if test "$AEM_DLL" -eq 1 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE -fi - -# -# define Fortran and C compile syntax -# -if test "$VKISOLVER" = VKI -then - SOLVERFLAGS="$SOLVERFLAGS -DVKI" -fi - -if test "$CASISOLVER" = CASI -then - SOLVERFLAGS="$SOLVERFLAGS -DCASI" -fi - -if test "$MF2SOLVER" = MF2PARALLEL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2PARALLEL" -fi -if test "$MF2SOLVER" = MF2SERIAL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2SERIAL" -fi - -if test "$INTELSOLVER" = PARDISO -then - SOLVERFLAGS="$SOLVERFLAGS -DPARDISO" -fi - -if test "$MUMPSSOLVER" = MUMPS -then - SOLVERFLAGS="$SOLVERFLAGS -DMUMPS" -fi - - -if test "$MARC_DLL" = MARC_DLL -then - SOLVERFLAGS="$SOLVERFLAGS -DMARC_DLL" -fi - -LINK_OPT= -DEBUG_OPT= -C_DEBUG_OPT= - -#Uncomment following line to build Marc in debuggable mode -MARCDEBUG= -#MARCDEBUG="ON" - -if test "$MARCDEBUG" = "ON" -then - LINK_OPT="-debug -traceback" - DEBUG_OPT="-debug -traceback" - C_DEBUG_OPT="-debug -traceback" -fi - - -MARCCHECK= -#MARCCHECK="ON" -if test "$MARCCHECK" = "ON" -then - DEBUG_OPT="$DEBUG_OPT -fpe0 -fp-stack-check -check all -ftrapuv " - C_DEBUG_OPT="$C_DEBUG_OPT -fp-stack-check -check-uninit -Wformat -ftrapuv " -fi - -MARCCODECOV= -#MARCCODECOV="ON" - -MARCCODEPROF= -#MARCCODEPROF="ON" - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - I8FFLAGS= - I8DEFINES= - I8CDEFINES= -else - I8FFLAGS="-i8" - I8DEFINES="-DI64" - I8CDEFINES="-U_DOUBLE -D_SINGLE" -fi - -MTHREAD=OPENMP -if test "$MARC_OPENMP" = "NONE" ; then - MTHREAD=NONE -fi -#MTHREAD=NONE -if test "$_OEM_NASTRAN" -ne 0 -then -MTHREAD=NONE -fi -if test "$AEM_DLL" -eq 1 -then - MTHREAD=NONE - CASISOLVER=NONE - VKISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - BCSGPUSOLVER=NONE - OPENSSL_LIB= - MARC_DLL=NONE - METISLIBS= -fi - -OMP_COMPAT=NO -OMP_COMPAT=YES -if test "$MTHREAD" = "NONE" -then -OMP_COMPAT=NO -fi - -CDEFINES= -FDEFINES= - -if test "$_OEM_NASTRAN" -ne 0 -then - CDEFINES="$CDEFINES -D_OEM_NASTRAN" - FDEFINES="$FDEFINES -D_OEM_NASTRAN" -fi - -FDEFINES="$FDEFINES -D_IMPLICITNONE" - -if test "$_OEM_NASTRAN" -eq 0 -then - FDEFINES="$FDEFINES -DMKL -DOPENMP" -fi - -if test "$OMP_COMPAT" = "YES" -then - FDEFINES="$FDEFINES -DOMP_COMPAT" -fi - -# -D_MSCMARC -FDEFINES="$FDEFINES -D_MSCMARC $DEBUG_OPT $MARC_SIMUFACT" -CDEFINES="$CDEFINES -D_MSCMARC $C_DEBUG_OPT $I8CDEFINES" - -if test "$AEM_DLL" -eq 1 -then - FDEFINES="$FDEFINES -D_AEMNL -DAAA" - CDEFINES="$CDEFINES -D_AEMNL -DAAA" -fi - -CINCL="-I$MARC_SOURCE/mdsrc -I$MARC_SOURCE/csource $METIS" -if test "$_OEM_NASTRAN" -ne 0 -then - CINCL="$CINCL -I../../include" -fi - -CC_OPT= -if test "$MTHREAD" = "OPENMP" -then - CC_OPT=" $CC_OPT -qopenmp" -fi - -CC="icc -c $CC_OPT -O1 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCLOW="icc -c $CC_OPT -O0 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCHIGH="icc -c $CC_OPT -O3 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - -if test "$MARCDEBUG" = "ON" -then - CC="icc -c $CC_OPT -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCLOW="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCHIGH="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -fi - -LOAD_CC="icc $CC_OPT -O1 -DLinux -DLINUX -DLinux_intel" -CCT="$CC" -CCTLOW="$CCLOW" -CCTHIGH="$CCHIGH" - -#PROFILE="-Mprof=func" -#PROFILE="-Mprof=lines" -#PROFILE="-Mprof=func,mpi" -PROFILE= -#PROFILE="-init=snan,arrays -CB -traceback -fpe0 -fp-stack-check -check all -check uninit -ftrapuv" -if test "$MARCCODECOV" = "ON" -then -PROFILE="-prof-gen=srcpos" -fi -if test "$MARCCODEPROF" = "ON" -then -PROFILE=" $PROFILE -pg" -fi - -FORT_OPT="-c -assume byterecl -safe_cray_ptr -mp1 -WB -fp-model source" -if test "$MTHREAD" = "OPENMP" -then - FORT_OPT=" $FORT_OPT -qopenmp" - if test "$OMP_COMPAT" = "YES" - then - FORT_OPT=" $FORT_OPT -qopenmp-threadprivate=compat" - fi -else -# FORT_OPT=" $FORT_OPT -auto " - FORT_OPT=" $FORT_OPT -save -zero" -fi - -FORTLOW="$FCOMP $FORT_OPT $PROFILE -O0 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTRAN="$FCOMP $FORT_OPT $PROFILE -O1 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTNA="$FCOMP $FORT_OPT -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -# for compiling free form f90 files. high opt, integer(4) -FORTF90="$FCOMP -c -O3" - -if test "$MARCDEBUG" = "ON" -then - FORTLOW="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTRAN="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTNA="$FCOMP $FORT_OPT -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -fi - -FORTLOWT="$FORTLOW" -FORTRANT="$FORTRAN" -FORTHIGHT="$FORTHIGH" - -FORTRANMNF="$FCOMP -c $FDEFINES " -CCMNF="icc -c -O1 -DLinux -DLINUX -DLinux_intel -Dport2egcs -I$MARC_SOURCE/marctoadams/mnf/include -D_LARGEFILE64_SOURCE" - -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - LOAD="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - LOADT="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - fi -# Uncomment the following lines to turn on the tracer and commnet out the next 5 lines -# if test $MPITYPE = intelmpi -# then -# INCLUDEMPI="-I$MPI_ROOT/include -I$VT_ROOT/include" -# LOAD="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# LOADT="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# fi - if test $MPITYPE = intelmpi - then - LOAD="ifort $PROFILE $LINK_OPT -o " - LOADT="ifort $PROFILE $LINK_OPT -o " - fi -else - LOAD="$FCOMP $LINK_OPT -o " - LOADT="$FCOMP $LINK_OPT -o " -fi - -if test "$MARC_DLL" = MARC_DLL -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide -lpthread" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - -if test "$AEM_DLL" -eq 1 -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - - -XLIBS="-L/usr/X11/lib -lX11 " - -# -# define archive and ranlib syntax -# - -ARC="ar rvl" -ARD="ar dvl" -ARX="ar xl" -RAN="" - -# -# choose which libraries you want to use ( e.g. blas ) -# - -if test "$VKISOLVER" = VKI -then - VKISOLVERLIBS="$MARC_LIB/vkisolver.a" -else - VKISOLVERLIBS= -fi - -if test "$CASISOLVER" = CASI -then - CASISOLVERLIBS="$CASILIB_DIR/libmarccasi.a $CASILIB_DIR/libcasi.a" -else - CASISOLVERLIBS= -fi - -MF2SOLVERLIBS= -if test "$MF2SOLVER" = MF2PARALLEL -then - MF2SOLVERLIBS="$MARC_LIB/mf2parallel/libseq.a \ - $MARC_LIB/mf2parallel/libsym.a \ - $MARC_LIB/mf2parallel/libmet.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libnum.a \ - $MARC_LIB/mf2parallel/libutl.a \ - $MARC_LIB/mf2parallel/libr8.a \ - $MARC_LIB/mf2parallel/libz.a " -fi - -if test "$MUMPSSOLVER" = MUMPS -then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - if test $MPITYPE = none - then - MUMPSSOLVERLIBS2= - echo hello > /dev/null - fi - if test $MPITYPE = intelmpi - then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a " - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a " - fi - fi - if test $MPITYPE = hpmpi - then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a" - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a" - fi - fi -else - MUMPSSOLVERLIBS= - MUMPSSOLVERLIBS2= -fi - -if test "$BCSGPUSOLVER" = BCSGPU -then - BCSSOLVERLIBS="${BCSLIB_DIR}/bcsgpulib.a " - MARCCUDALIBS1="-L${BCSLIB_DIR}/cuda_dummy -lmarccuda " - MARCCUDALIBS2="-L${BCSLIB_DIR}/cuda -lmarccuda " - MARCCUDALIBS=$MARCCUDALIBS1 -else - BCSSOLVERLIBS="${MARC_LIB}/bcslib.a " -fi -if test "$AEM_DLL" -eq 1 -then - BCSSOLVERLIBS= -fi - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - MKLLIB="$MARC_MKL/libmkl_scalapack_lp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_lp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -else - MKLLIB="$MARC_MKL/libmkl_scalapack_ilp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_ilp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -fi - -SECLIBS="-L$MARC_LIB -llapi" - -SOLVERLIBS="${BCSSOLVERLIBS} ${VKISOLVERLIBS} ${CASISOLVERLIBS} ${MF2SOLVERLIBS} \ - $MKLLIB -L$MARC_MKL -liomp5 \ - $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/kdtree2.a " - -SOLVERLIBS_DLL=${SOLVERLIBS} -if test "$AEM_DLL" -eq 1 -then -SOLVERLIBS_DLL="$MKLLIB -L$MARC_MKL -liomp5 $MARC_LIB/blas_src.a" -fi -MRCLIBS="$MARC_LIB/clib.a ${CASISOLVERLIBS}" -MRCLIBSPAR="$MARC_LIB/clib.a" -STUBS="$MARC_LIB/stubs.a " -MNFLIBS="$MARC_LIB/libmnf.a" -MDUSER="$MARC_LIB/md_user.a" -if test "X$MARC_SIMUFACT" != "X" -then - SFLIB="-L$SFMATDIR -lMBA_Grain $SFMATDIR/sfclib.a " -else - SFLIB=" " -fi - -OPENMP="-qopenmp" - -if test "$AEM_DLL" -eq 1 -then - LOAD_DLL=$LOAD - OPENMP= - LIBMNF= - OPENSSL=NONE -fi - -SYSLIBS=" $OPENMP -lpthread -shared-intel -cxxlib" - -# Uncomment the following lines to turn on the trace and comment out the next 4 lines -# if test $MPITYPE = intelmpi -# then -# SYSLIBS="-L${VT_ROOT}/lib -lVT -ldwarf -lelf -lm -lpthread \ -# -L${MPI_ROOT}/lib64 -lmpi -lmpiif -lmpigi -lrt" -# fi -if test $MPITYPE = intelmpi -then - SYSLIBS="-L${MPI_ROOT}/lib -lmpi_mt -lmpifort -lrt $OPENMP -threads -lpthread -shared-intel -cxxlib" -fi - - -SYSLIBSPAR=" " - -MARC_DLL_CODES="runmarc.f" - - -BLAS_SRC="dzero.f icopy.f izero.f" -if test "$_OEM_NASTRAN" -ne 0 -then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - BLAS_SRC="$BLAS_SRC dsctr.f zsctr.f dzasum.f daxpyi.f zaxpyi.f dgthr.f zgthr.f" - else - BLAS_SRC="ALL" - fi -fi - -LOW_OPT_CODES="are163.f contro.f ndext.f omarc.f omarca.f omarcb.f omarcc.f \ - omars.f fixbc.f triang.f bet049.f norst3.f eldata.f \ - elec*.f elct*.f fmeig.f oada00.f ogeig.f updtrbe2.f cycrota.f \ - cordef.f ogpk.f ogtan.f eldam.f formrbe3.f \ - inertie.f em_sso072.f cn_fol3d_qpatch6.f cosim_begin.f" -if test "$MARC_INTEGER_SIZE" = "i8" ; then - LOW_OPT_CODES="$LOW_OPT_CODES bbcseg.f" -fi - -HIGH_OPT_CODES="dpsmsa1.f dpsmsa2.f dpsmsa3.f dpsmsa4.f dpsmsa5.f dpsmsa6.f \ - dpsmsa7.f dpsmsa8.f dpsmsa9.f dpsmsa10.f dpsmsa11.f dpsmsa12.f \ - dpsmsa13.f dpsmsa14.f dpsmsa15.f dpsmsa16.f dpsmsah.f tpsmsah.f cn_qsort4_11.f " - - - -MAXNUM=1000000 diff --git a/installation/mods_MarcMentat/2018/Marc_tools/run_damask_hmp b/installation/mods_MarcMentat/2018/Marc_tools/run_damask_hmp deleted file mode 100644 index cfd8ab35f..000000000 --- a/installation/mods_MarcMentat/2018/Marc_tools/run_damask_hmp +++ /dev/null @@ -1,4131 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -autorst auto restart flag for auto forge . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - - -# getting user subroutine file name -found=0 -for i in "$@"; do - if test $found = 1; then - DAMASK_USER=$i - found=0 - fi - case $i in - -u* | -U*) - found=1 - ;; - esac -done -# sourcing include_linux64 (needs DAMASK_USER to be set) -. $MARC_INCLUDE - -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$SFMATDIR:$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usernoext= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto=0 -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - if test ! -f $user - then - error="$error -user subroutine file $user not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$nauto" - then - if test $nauto -gt 2 - then - error="$error -incorrect option for auto restart " - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" -fi -fi - -if test $nprocd -gt 1 -then - if test $nauto -gt 0 - then - error="$error -cannot run DDM job with auto restart (-au) option " - fi -fi -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto " >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($user)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Auto Restart option ($nauto)? $ECHOTXT" - read value - if test "$value" - then - nauto=$value - fi - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# -# add DAMASK options for linking - DAMASK="-lstdc++" - - if test "$user" - then - program=$usernoext.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$usernoext.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $nauto -gt 0 -o $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $nauto -gt 0 -then - RUN_JOB="$RUN_JOB -autorst $nauto " -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -############################################################################## -# run marc using valgrind # -############################################################################## -#RUN_JOB="valgrind $RUN_JOB" -#RUN_JOB="valgrind --read-var-info=yes --gen-suppressions=yes $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=all -v $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=yes --error-limit=no $RUN_JOB" -############################################################################## - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$usermoext.o - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test $MACHINENAME = "CRAY" - then - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTHIGHMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTHIGHMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTHIGHMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - $RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2018/Marc_tools/run_damask_lmp b/installation/mods_MarcMentat/2018/Marc_tools/run_damask_lmp deleted file mode 100644 index 599e8c523..000000000 --- a/installation/mods_MarcMentat/2018/Marc_tools/run_damask_lmp +++ /dev/null @@ -1,4131 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -autorst auto restart flag for auto forge . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - - -# getting user subroutine file name -found=0 -for i in "$@"; do - if test $found = 1; then - DAMASK_USER=$i - found=0 - fi - case $i in - -u* | -U*) - found=1 - ;; - esac -done -# sourcing include_linux64 (needs DAMASK_USER to be set) -. $MARC_INCLUDE - -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$SFMATDIR:$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usernoext= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto=0 -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - if test ! -f $user - then - error="$error -user subroutine file $user not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$nauto" - then - if test $nauto -gt 2 - then - error="$error -incorrect option for auto restart " - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" -fi -fi - -if test $nprocd -gt 1 -then - if test $nauto -gt 0 - then - error="$error -cannot run DDM job with auto restart (-au) option " - fi -fi -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto " >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($user)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Auto Restart option ($nauto)? $ECHOTXT" - read value - if test "$value" - then - nauto=$value - fi - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# -# add DAMASK options for linking - DAMASK="-lstdc++" - - if test "$user" - then - program=$usernoext.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$usernoext.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $nauto -gt 0 -o $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $nauto -gt 0 -then - RUN_JOB="$RUN_JOB -autorst $nauto " -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -############################################################################## -# run marc using valgrind # -############################################################################## -#RUN_JOB="valgrind $RUN_JOB" -#RUN_JOB="valgrind --read-var-info=yes --gen-suppressions=yes $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=all -v $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=yes --error-limit=no $RUN_JOB" -############################################################################## - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$usermoext.o - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test $MACHINENAME = "CRAY" - then - $DFORTLOWMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTLOWMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_lmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTLOWMP $user || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTLOWMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_lmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTLOWMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTLOWMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - $RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2018/Marc_tools/run_damask_mp b/installation/mods_MarcMentat/2018/Marc_tools/run_damask_mp deleted file mode 100644 index 5261654e3..000000000 --- a/installation/mods_MarcMentat/2018/Marc_tools/run_damask_mp +++ /dev/null @@ -1,4131 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -autorst auto restart flag for auto forge . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - - -# getting user subroutine file name -found=0 -for i in "$@"; do - if test $found = 1; then - DAMASK_USER=$i - found=0 - fi - case $i in - -u* | -U*) - found=1 - ;; - esac -done -# sourcing include_linux64 (needs DAMASK_USER to be set) -. $MARC_INCLUDE - -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$SFMATDIR:$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usernoext= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto=0 -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - if test ! -f $user - then - error="$error -user subroutine file $user not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$nauto" - then - if test $nauto -gt 2 - then - error="$error -incorrect option for auto restart " - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" -fi -fi - -if test $nprocd -gt 1 -then - if test $nauto -gt 0 - then - error="$error -cannot run DDM job with auto restart (-au) option " - fi -fi -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto " >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($user)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Auto Restart option ($nauto)? $ECHOTXT" - read value - if test "$value" - then - nauto=$value - fi - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# -# add DAMASK options for linking - DAMASK="-lstdc++" - - if test "$user" - then - program=$usernoext.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$usernoext.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $nauto -gt 0 -o $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $nauto -gt 0 -then - RUN_JOB="$RUN_JOB -autorst $nauto " -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -############################################################################## -# run marc using valgrind # -############################################################################## -#RUN_JOB="valgrind $RUN_JOB" -#RUN_JOB="valgrind --read-var-info=yes --gen-suppressions=yes $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=all -v $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=yes --error-limit=no $RUN_JOB" -############################################################################## - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$usermoext.o - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test $MACHINENAME = "CRAY" - then - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTRANMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTRANMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTRANMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - $RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2018/Marc_tools/run_marc.original b/installation/mods_MarcMentat/2018/Marc_tools/run_marc.original deleted file mode 100644 index 7fb63b063..000000000 --- a/installation/mods_MarcMentat/2018/Marc_tools/run_marc.original +++ /dev/null @@ -1,4209 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -autorst auto restart flag for auto forge . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - -. $MARC_INCLUDE -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$SFMATDIR:$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usersubname= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto=0 -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user - basefile=`$BASENAME $value` - if test ${basefile##*.} = f - then - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user.f - elif test ${basefile##*.} = F - then - user=`dirname $value`/`$BASENAME $value .F` - usersubname=$user.F - elif test ${basefile##*.} = f90 - then - user=`dirname $value`/`$BASENAME $value .f90` - usersubname=$user.f90 - elif test ${basefile##*.} = F90 - then - user=`dirname $value`/`$BASENAME $value .F90` - usersubname=$user.F90 - fi - case $user in - \/*) - ;; - *) - user=`pwd`/$user - usersubname=`pwd`/$usersubname - ;; - esac - if test ! -f $usersubname - then - if test -f $usersubname.f - then - usersubname=$usersubname.f - elif test -f $usersubname.F - then - usersubname=$usersubname.F - elif test -f $usersubname.f90 - then - usersubname=$usersubname.f90 - elif test -f $usersubname.F90 - then - usersubname=$usersubname.F90 - fi - fi - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a_$value" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$usersubname" - then - if test ! -f $usersubname - then - error="$error -user subroutine file $usersubname not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$nauto" - then - if test $nauto -gt 2 - then - error="$error -incorrect option for auto restart " - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" - fi -fi - -if test $nprocd -gt 1 -then - if test $nauto -gt 0 - then - error="$error -cannot run DDM job with auto restart (-au) option " - fi -fi -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $usersubname -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto " >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $usersubname -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit -Auto Restart : $nauto" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($usersubname)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user - basefile=`$BASENAME $value` - if test ${basefile##*.} = f - then - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user.f - elif test ${basefile##*.} = F - then - user=`dirname $value`/`$BASENAME $value .F` - usersubname=$user.F - elif test ${basefile##*.} = f90 - then - user=`dirname $value`/`$BASENAME $value .f90` - usersubname=$user.f90 - elif test ${basefile##*.} = F90 - then - user=`dirname $value`/`$BASENAME $value .F90` - usersubname=$user.F90 - fi - case $user in - \/*) - ;; - *) - user=`pwd`/$user - usersubname=`pwd`/$usersubname - ;; - esac - if test ! -f $usersubname - then - if test -f $usersubname.f - then - usersubname=$usersubname.f - elif test -f $usersubname.F - then - usersubname=$usersubname.F - elif test -f $usersubname.f90 - then - usersubname=$usersubname.f90 - elif test -f $usersubname.F90 - then - usersubname=$usersubname.F90 - fi - fi - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Auto Restart option ($nauto)? $ECHOTXT" - read value - if test "$value" - then - nauto=$value - fi - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# - - if test "$user" - then -# program=$user.marc - program=$DIRJOB/`$BASENAME $user .f`.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$DIRJOB/`$BASENAME $user .f`.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $nauto -gt 0 -o $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $nauto -gt 0 -then - RUN_JOB="$RUN_JOB -autorst $nauto " -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -############################################################################## -# run marc using valgrind # -############################################################################## -#RUN_JOB="valgrind $RUN_JOB" -#RUN_JOB="valgrind --read-var-info=yes --gen-suppressions=yes $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=all -v $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=yes --error-limit=no $RUN_JOB" -############################################################################## - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$DIRJOB/`$BASENAME $user .f`.o - basefile=`$BASENAME $usersubname` - if test ${basefile##*.} = f - then - usersub=$DIRJOB/`$BASENAME $user .f`.F - ln -sf "$user.f" "$usersub" - else - usersub=$usersubname - fi - - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test ${basefile##*.} = f - then - ln -sf "$user.f" "$usersub" - fi - if test $MACHINENAME = "CRAY" - then - $FORTRAN $usersub || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $FORTRAN $usersub -o $userobj || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - if test ${basefile##*.} = f - then - /bin/rm -f "$usersub" - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=`basename $usersubname .f` - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user.f $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user.f on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser.f 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user.f on host `hostname`" - fi - userobj=$DIRJOB/`$BASENAME $user .f`.o - basefile=`$BASENAME $usersubname` - if test ${basefile##*.} = f - then - usersub=$DIRJOB/`$BASENAME $user .f`.F - ln -sf "$user.f" "$usersub" - else - usersub=$usersubname - fi - if test $MACHINENAME = "CRAY" - then - $FORTRAN $usersub || \ - { - echo "$0: compile failed for $user.f" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $FORTRAN $usersub -o $userobj || \ - { - echo "$0: compile failed for $user.f" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - if test ${basefile##*.} = f - then - /bin/rm -f "$usersub" - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi - fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=`basename $usersubname .f` - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user.f $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user.f on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser.f 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user.f on host `hostname`" - fi - userobj=$DIRJOB/`$BASENAME $user .f`.o - basefile=`$BASENAME $usersubname` - if test ${basefile##*.} = f - then - usersub=$DIRJOB/`$BASENAME $user .f`.F - ln -sf "$user.f" "$usersub" - else - usersub=$usersubname - fi - if test $MACHINENAME = "CRAY" - then - $FORTRAN $usersub || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $FORTRAN $usersub -o $userobj || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - if test ${basefile##*.} = f - then - /bin/rm -f "$usersub" - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null - -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - -$RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi - fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=`basename $usersubname .f` - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2018/Mentat_bin/edit_window b/installation/mods_MarcMentat/2018/Mentat_bin/edit_window deleted file mode 100644 index b732a7694..000000000 --- a/installation/mods_MarcMentat/2018/Mentat_bin/edit_window +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -# This script opens a window running an editor. -# The command to invoke the editor is specified during DAMASK installation - -%EDITOR% $* \ No newline at end of file diff --git a/installation/mods_MarcMentat/2018/Mentat_bin/edit_window.original b/installation/mods_MarcMentat/2018/Mentat_bin/edit_window.original deleted file mode 100644 index 64c0a68d0..000000000 --- a/installation/mods_MarcMentat/2018/Mentat_bin/edit_window.original +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh -# This script opens a window running an editor. The default window is an -# xterm, and the default editor is vi. These may be customized. - -dir= -for d in /usr/bin /usr/bin/X11; do - if test -x "$d/xterm"; then - dir="$d" - break - fi -done - -if test -z "$dir"; then - echo "$0: Could not find xterm" - exit 1 -fi - -"$dir/xterm" -T "vi $*" -n "vi $*" -e vi $* diff --git a/installation/mods_MarcMentat/2018/Mentat_bin/kill1.original b/installation/mods_MarcMentat/2018/Mentat_bin/kill1.original deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2018/Mentat_bin/kill1.original +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2018/Mentat_bin/kill4 b/installation/mods_MarcMentat/2018/Mentat_bin/kill4 deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2018/Mentat_bin/kill4 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2018/Mentat_bin/kill5 b/installation/mods_MarcMentat/2018/Mentat_bin/kill5 deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2018/Mentat_bin/kill5 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2018/Mentat_bin/kill6 b/installation/mods_MarcMentat/2018/Mentat_bin/kill6 deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2018/Mentat_bin/kill6 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2018/Mentat_bin/submit1.original b/installation/mods_MarcMentat/2018/Mentat_bin/submit1.original deleted file mode 100644 index 06a7b93b8..000000000 --- a/installation/mods_MarcMentat/2018/Mentat_bin/submit1.original +++ /dev/null @@ -1,186 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=/tmp/msc/marc2018 -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -autorst=$4 -copy_datfile="-ci $5" -copy_postfile="-cr $6" -scr_dir=$7 -dcoup=$8 -assem_recov_nthread=$9 -shift 9 # cannot use $10, $11, ... -nthread=$1 -nsolver=$2 -mode=$3 -gpu=$4 - -if [ "$slv" != "" -a "$slv" != "marc" ]; then - slv="-iam sfm" -else - slv="" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_marc" $slv -j $job -v n -b y $nprocds $nprocd -autorst $autorst \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2018/Mentat_bin/submit4 b/installation/mods_MarcMentat/2018/Mentat_bin/submit4 deleted file mode 100644 index f25a2004e..000000000 --- a/installation/mods_MarcMentat/2018/Mentat_bin/submit4 +++ /dev/null @@ -1,187 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=%INSTALLDIR%/marc%VERSION% -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -autorst=$4 -copy_datfile="-ci $5" -copy_postfile="-cr $6" -scr_dir=$7 -dcoup=$8 -assem_recov_nthread=$9 -shift 9 # cannot use $10, $11, ... -nthread=$1 -nsolver=$2 -mode=$3 -gpu=$4 - -if [ "$slv" != "" -a "$slv" != "marc" ]; then - slv="-iam sfm" -else - slv="" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile=${srcfile%.*}".marc" - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_damask_hmp" $slv -j $job -v n -b y $nprocds $nprocd -autorst $autorst \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2018/Mentat_bin/submit5 b/installation/mods_MarcMentat/2018/Mentat_bin/submit5 deleted file mode 100644 index 786f6efc5..000000000 --- a/installation/mods_MarcMentat/2018/Mentat_bin/submit5 +++ /dev/null @@ -1,187 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=%INSTALLDIR%/marc%VERSION% -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -autorst=$4 -copy_datfile="-ci $5" -copy_postfile="-cr $6" -scr_dir=$7 -dcoup=$8 -assem_recov_nthread=$9 -shift 9 # cannot use $10, $11, ... -nthread=$1 -nsolver=$2 -mode=$3 -gpu=$4 - -if [ "$slv" != "" -a "$slv" != "marc" ]; then - slv="-iam sfm" -else - slv="" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile=${srcfile%.*}".marc" - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_damask_mp" $slv -j $job -v n -b y $nprocds $nprocd -autorst $autorst \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2018/Mentat_bin/submit6 b/installation/mods_MarcMentat/2018/Mentat_bin/submit6 deleted file mode 100644 index 6a5d9d79f..000000000 --- a/installation/mods_MarcMentat/2018/Mentat_bin/submit6 +++ /dev/null @@ -1,187 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=%INSTALLDIR%/marc%VERSION% -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -autorst=$4 -copy_datfile="-ci $5" -copy_postfile="-cr $6" -scr_dir=$7 -dcoup=$8 -assem_recov_nthread=$9 -shift 9 # cannot use $10, $11, ... -nthread=$1 -nsolver=$2 -mode=$3 -gpu=$4 - -if [ "$slv" != "" -a "$slv" != "marc" ]; then - slv="-iam sfm" -else - slv="" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile=${srcfile%.*}".marc" - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_damask_lmp" $slv -j $job -v n -b y $nprocds $nprocd -autorst $autorst \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2018/Mentat_menus/job_run.ms b/installation/mods_MarcMentat/2018/Mentat_menus/job_run.ms deleted file mode 100644 index 388aba2e8..000000000 --- a/installation/mods_MarcMentat/2018/Mentat_menus/job_run.ms +++ /dev/null @@ -1,2697 +0,0 @@ -#ifndef AUTOFORGE -popmenu job_title_pm file jobs.ms -popdown job_title_ok file jobs.ms - -group user_domains_gr file domain_decomposition.ms -group user_domains_generate_gr file domain_decomposition.ms -group user_domains_tail_gr file domain_decomposition.ms -group matrix_solver_gr file job_common.ms -popmenu ddm_options file job_common.ms - -browser edit_browser file file.ms -browser directory_browser file file.ms -screen domains file domain_decomposition.ms - - - - browser usersub_file_browser { - position 0 0 - size 82 72 - text "$usersub_file_browser_label" ($usersub_file_browser_label) - filter "*.f *.F *.f90 *.F90" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$usersub_file_browser_command" ($usersub_file_browser_command) - } - - - - browser host_file_browser { - position 0 0 - size 82 72 - text "$host_file_browser_label" ($host_file_browser_label) - filter "*" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$host_file_browser_command" ($host_file_browser_command) - } - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_popmenu { - - text "RUN JOB" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - button { - position 1 9 - size 24 4 - text "USER SUBROUTINE FILE" - browser usersub_file_browser - settext $usersub_file_browser_label "SELECT USER SUBROUTINE FILE" - set $usersub_file_browser_command "*job_usersub_file" - help job_usersub_file - } - - toggle { - position +26 = - size 22 4 - text "SELECTED USER SUBS" - toggle job_usersubs - help job_run_seluser - visible job_usersubs - popmenu job_usersub_pm - } - - display { - position 1 +4 - size 50 4 - display job_usersub_file - } - - button { - position 1 +4 - size 12 4 - text "EDIT" - command "*job_edit_usersub_file" - visible job_usersub_file - } - - button { - position +12 = - size 12 4 - text "CLEAR" - command "*job_clear_usersub_file" - visible job_usersub_file - } - - roller { - position +12 = - size 26 4 - nvalues 3 - texts "COMPILE / NO SAVE" - "COMPILE AND SAVE" - "RUN SAVED EXECUTABLE" - help job_run_compile - roller "job_option user_source" - visible job_usersub_file - commands "*job_option user_source:compile_nosave" - "*job_option user_source:compile_save" - "*job_option user_source:run_saved" - } - - button { - position 1 +6 - size 24 4 - text "SOLVER/PARALLELIZATION" - help job_run_parallel - popmenu job_run_parallelization_pm - set $popname2 "job_run_parallelization_pm" - } - frame { - position 1 +4 - size 48 16 - border_width 1 - border_color black - - group{ - layout hbox - frame { - position 0 0 - size 24 16 - group { - layout vbox - - display { - position 0 0 - size 24 4 - display job_solver_solution - } - - display { - position = +4 - size 24 4 - display job_solver_type - } - spacer { - stretch 1 - } - - } - } - - frame { - position +22 = - size 24 16 - border_width 1 - border_color black - - group { - #layout vbox - display { - position = +4 - size 24 4 - display job_ddm_domains - } - - display { - position = +4 - size 24 4 - display job_assem_recov_nthreads - } - - display { - position = +4 - size 24 4 - display job_solver_procs - visible solver_allows_multi_procs - } - - display { - position = = - size 24 4 - display job_solver_threads - visible "and(solver_allows_multi_threads,\ - not(and(job_solver_mfront_sparse,\ - *job_option parallel:on)))" - } - - display { - position = +4 - size 24 4 - display job_solver_gpu - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } - } - } - } - } - - button { - position 1 +18 - size 8 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - -# see also job_common.ms -# see also the ADVANCED JOB SUBMISSION popmenu in this file - - label { - position +10 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - button { - position +20 = - size 13 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position 1 +6 - size 16 6 - text "SUBMIT (1)" - command "*submit_job 1 *monitor_job" - } - - button { - position +16 = - size 16 6 - text "ADVANCED JOB SUBMISSION" - popmenu job_submit_adv_pm - } - - button { - position +16 = - size 18 6 - text "DAMASK" - popmenu damask - } - - button { - position 1 +6 - size 16 6 - text "UPDATE" - command "*update_job" - } - - button { - position +16 = - size 16 6 - text "MONITOR" - command "*monitor_job" - } - - button { - position +16 = - size 18 6 - text "KILL" - command "*kill_job *monitor_job" - } - - label { - position 1 +7 - size 32 4 - text "STATUS" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_status" - } - - label { - position -32 +4 - size 32 4 - text "CURRENT INCREMENT (CYCLE)" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_increment" - } - - label { - position -32 +4 - size 32 4 - text "SINGULARITY RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_singularity_ratio" - } - - label { - position -32 +4 - size 32 4 - text "CONVERGENCE RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_convergence_ratio" - } - - label { - position 1 +4 - size 32 4 - text "ANALYSIS TIME" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_analysis_time" - } - - label { - position -32 +4 - size 32 4 - text "WALL TIME" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_time" - } - - frame { - position 1 +4 - size 50 8 - - group { - - frame { - position 0 0 - size 50 8 - text "TOTAL" - border_width 1 - border_color black - group { - - label { - position +6 = - size 13 4 - text "CYCLES" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_cycles" - border_width 1 - border_color black - } - - label { - position -13 +4 - size 13 4 - text "SEPARATIONS" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_separations" - border_width 1 - border_color black - } - - label { - position +10 -4 - size 11 4 - text "CUT BACKS" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_cut_backs" - border_width 1 - border_color black - } - - label { - position -11 +4 - size 11 4 - text "REMESHES" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_remeshes" - border_width 1 - border_color black - } - } - } - } - } - - label { - position 1 +8 - size 19 4 - text "EXIT NUMBER" - border_width 1 - border_color black - } - - integer { - position +19 = - size 10 4 - display "job_exit" - } - - button { - position +10 = - size 21 4 - text "EXIT MESSAGE" - popmenu job_exit_msg_pm - help exit_message - } - - label { - position 1 +6 - size 7 4 - text "EDIT" - border_width 1 - border_color black - } - - button { - position +7 = - size 12 4 - text "OUTPUT FILE" - command "*job_edit_output" - } - - button { - position +12 = - size 9 4 - text "LOG FILE" - command "*job_edit_log_file" - } - - button { - position +9 = - size 12 4 - text "STATUS FILE" - command "*job_edit_status_file" - } - - button { - position +12 = - size 10 4 - text "ANY FILE" - settext $edit_browser_label "EDIT FILE" - set $edit_browser_command "*edit_file" - browser edit_browser - help edit_file - } - - popdown { - position 1 +6 - size 32 4 - text "OPEN POST FILE (MODEL PLOT RESULTS MENU)" - command "@popdown(job_properties_pm) @main(results) @popup(modelplot_pm) *post_open_default" - } - - button { - position 1 +6 - size 12 8 - text "RESET" - command "*job_submit_reset" - } - - popdown { - position +38 = - size 12 8 - text "OK" - } - } - - window job_run_wi { - parent mentat - origin 35 1 - size 52 115 - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_usersub_pm { - - text "CURRENTLY SELECTED USER SUBROUTINES" - - group { - - - display { - position 1 +5 - size 64 86 - display "job_usersubs" - } - - popdown { - position 27 +88 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 66 102 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_submit_adv_pm { - - text "ADVANCED JOB SUBMISSION" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - label { - position 1 9 - size 19 4 - text "INITIAL ALLOCATION" - border_width 1 - border_color black - } - label { - position +19 = - size 15 4 - text "GENERAL MEMORY" - help job_param_general_init_allocation - } - text { - position +15 = - size 10 4 - display "job_param_value_general_init_allocation" - command "*job_param general_init_allocation" - help job_param_general_init_allocation - } - - label { - position +10 = - size 4 4 - text "MB" - border_width 1 - border_color black - } - - toggle { - position 1 +5 - size 32 4 - text "OUT-OF-CORE ELEMENT STORAGE" - help job_param_elsto - toggle "*job_option elsto:on" - true_command "*job_option elsto:on" - false_command "*job_option elsto:off" - } - - toggle { - position 1 +4 - size 32 4 - text "OUT-OF-CORE INCREMENTAL BACKUP" - help job_param_inc_backup_storage - toggle "*job_option inc_backup_storage:out_of_core" - true_command "*job_option inc_backup_storage:out_of_core" - false_command "*job_option inc_backup_storage:in_core" - } - - toggle { - position +34 = - size 14 4 - text "CHECK SIZES" - help job_run_check - toggle "*job_option check:on" - true_command "*job_option check:on" - false_command "*job_option check:off" - } - - frame { - position 1 +6 - size 48 12 - text "MARC INPUT FILE" - border_width 1 - border_color black - - group { - - label { - position 0 4 - size 9 4 - text "VERSION" - border_width 1 - border_color black - } - - roller { - position +9 = - size 14 4 - nvalues 25 - nvisible 25 - texts "DEFAULT" -#if 0 - "2018" -#endif - "2017.1" - "2017" - "2016" - "2015" - "2014.2" - "2014.1" - "2014" - "2013.1" - "2013" - "2012" - "2011" - "2010.2" - "2010" - "2008" - "2007" - "2005R3" - "2005" - "2003" - "2001" - "2000" -#if 0 - "8" -#endif - "K7" - "K6.2" - "K5" - "K4" - help job_param_version - rollers "job_input_version_default" -#if 0 - "job_input_version_2018" -#endif - "job_input_version_2017.1" - "job_input_version_2017" - "job_input_version_2016" - "job_input_version_2015" - "job_input_version_2014.2" - "job_input_version_2014.1" - "job_input_version_2014" - "job_input_version_2013.1" - "job_input_version_2013" - "job_input_version_2012" - "job_input_version_2011" - "job_input_version_2010.2" - "job_input_version_2010" - "job_input_version_2008" - "job_input_version_2007" - "job_input_version_2005r3" - "job_input_version_2005" - "job_input_version_2003" - "job_input_version_2001" - "job_input_version_2000" -#if 0 - "job_input_version_8" -#endif - "job_input_version_k7" - "job_input_version_k6" - "job_input_version_k5" - "job_input_version_k4" - commands "*job_option version:default" -#if 0 - "*job_option version:2018" -#endif - "*job_option version:2017.1" - "*job_option version:2017" - "*job_option version:2016" - "*job_option version:2015" - "*job_option version:2014.2" - "*job_option version:2014.1" - "*job_option version:2014" - "*job_option version:2013.1" - "*job_option version:2013" - "*job_option version:2012" - "*job_option version:2011" - "*job_option version:2010.2" - "*job_option version:2010" - "*job_option version:2008" - "*job_option version:2007" - "*job_option version:2005r3" - "*job_option version:2005" - "*job_option version:2003" - "*job_option version:2001" - "*job_option version:2000" -#if 0 - "*job_option version:8" -#endif - "*job_option version:k7" - "*job_option version:k6" - "*job_option version:k5" - "*job_option version:k4" - visibles "job_allows_input_version_default" -#if 0 - "job_allows_input_version_2018" -#endif - "job_allows_input_version_2017.1" - "job_allows_input_version_2017" - "job_allows_input_version_2016" - "job_allows_input_version_2015" - "job_allows_input_version_2014.2" - "job_allows_input_version_2014.1" - "job_allows_input_version_2014" - "job_allows_input_version_2013.1" - "job_allows_input_version_2013" - "job_allows_input_version_2012" - "job_allows_input_version_2011" - "job_allows_input_version_2010.2" - "job_allows_input_version_2010" - "job_allows_input_version_2008" - "job_allows_input_version_2007" - "job_allows_input_version_2005r3" - "job_allows_input_version_2005" - "job_allows_input_version_2003" - "job_allows_input_version_2001" - "job_allows_input_version_2000" -#if 0 - "job_allows_input_version_8" -#endif - "job_allows_input_version_k7" - "job_allows_input_version_k6" - "job_allows_input_version_k5" - "job_allows_input_version_k4" - } - -# see also job_common.ms -# see also the RUN JOB popmenu in this file - - label { - position +14 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - toggle { - position 0 +4 - size 24 4 - text "EXTENDED PRECISION" - help job_run_precision - toggle "*job_option inp_file_prec:extended" - true_command "*job_option inp_file_prec:extended" - false_command "*job_option inp_file_prec:normal" - } - toggle { - position +24 = - size 24 4 - text "INCLUDE UNUSED TABLES" - toggle "*job_option input_file_tables:all" - true_command "*job_option input_file_tables:all" - false_command "*job_option input_file_tables:used" - } - } - } - - button { - position 1 +14 - size 24 4 - text "SCRATCH DIRECTORY" - settext $directory_browser_label "JOB SCRATCH DIRECTORY" - set $directory_browser_command "*job_scratch_directory" - browser directory_browser - help job_scratch_directory - } - - button { - position +24 = - size 24 4 - text "CLEAR" - command "*job_clear_scratch_directory" - visible job_scratch_directory - } - - text { - position 1 +4 - size 48 4 - display job_scratch_dir - command "*job_scratch_directory" - } - -#ifdef DCOM - toggle { - position 1 +6 - size 8 4 - text "\{DCOM}" - toggle "*job_option dcom:on" - help job_run_dcom - true_command "*job_option dcom:on" - false_command "*job_option dcom:off" - visible win32_available - } - - button { - position +8 = - size 12 4 - text "HOSTNAME" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } - - text job_dcom_hostname { - position +12 = - size 28 4 - display "job_dcom_hostname" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } -#endif - - button { - position 1 +6 - size 24 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - - button { - position +24 = - size 24 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position +4 +6 - size 20 4 - text "WRITE INPUT FILE" - command "*job_write_input" - } - - button { - position = +4 - size 20 4 - text "EDIT INPUT FILE" - command "*job_edit_input" - } - - popdown { - position 1 +5 - size 20 6 - text "SUBMIT 1" - command "*submit_job 1 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 1" - command "*execute_job 1 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 2" - command "*submit_job 2 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 2" - command "*execute_job 2 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 3" - command "*submit_job 3 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 3" - command "*execute_job 3 *monitor_job" - } - - popdown { - position 19 +8 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 -#ifdef DCOM - size 50 100 -#else - size 50 94 -#endif - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - -#-------------------------------------------------------------------------------------------------- -popmenu damask { - -#ifdef QT_MENTAT - text "DAMASK.MPIE.DE" -#endif - - group { -#ifndef QT_MENTAT - label { - position 0 0 - size 50 4 - text "DAMASK.MPIE.DE" - } -#endif - - label { - position 1 6 - size 13 6 - text "Optimzation" - border_width 1 - border_color black - } - - label { - position +13 = - size 20 6 - text "write Input" - border_width 1 - border_color black - } - - label { - position +18 = - size 30 6 - text "do not write Inp." - border_width 1 - border_color black - } - - label { - position -32 +6 - size 12 6 - text "O2 / OpenMP" - border_width 1 - border_color black - } - - popdown { - position +12 = - size 20 6 - text "Submit" - command "*submit_job 4 *monitor_job" - } - - popdown { - position +20 = - size 20 6 - text "Execute" - command "*execute_job 4 *monitor_job" - } - - label { - position -32 +6 - size 12 6 - text "O1 / OpenMP" - border_width 1 - border_color black - } - - popdown { - position +12 = - size 20 6 - text "Submit" - command "*submit_job 5 *monitor_job" - } - - popdown { - position +20 = - size 20 6 - text "Execute" - command "*execute_job 5 *monitor_job" - } - - label { - position -32 +6 - size 12 6 - text "O0 / OpenMP" - border_width 1 - border_color black - } - - popdown { - position +12 = - size 20 6 - text "Submit" - command "*submit_job 6 *monitor_job" - } - - popdown { - position +20 = - size 20 6 - text "Execute" - command "*execute_job 6 *monitor_job" - } - - popdown { - position 19 +8 - size 12 8 - text "CANCEL" - } -} - - - - window { - parent mentat - origin 38 8 -#ifdef DCOM - size 50 100 -#else - size 50 94 -#endif - background_color body - border_width 1 - border_color border - buffering single - } - mode permanent -} - -#-------------------------------------------------------------------------------------------------- -popmenu job_exit_msg_pm { - - text "EXIT MESSAGE" - - group { - - - - text { - position 1 5 - size 84 74 - multiline - readonly - display "job_exit_msg" - } - - popdown { - position 37 +76 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 86 90 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_parallelization_pm { - - text "SOLVER/PARALLELIZATION" - - group { - layout vbox - frame { - position 0 0 - size 42 8 - group { - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 36 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 36 4 - display job_class_label - } - } - } - frame { - position 0 8 - size 42 20 - group job_ddm_gr - text "DOMAIN DECOMPOSITION" - border_width 1 - border_color black - } - - frame { - position 0 +20 - size 42 13 - group job_assem_recov_gr - text "ASSEMBLY AND RECOVERY" - border_width 1 - border_color black - } - - frame { - position 0 +14 - size 42 31 - group job_parallel_matrix_solver_gr - text "MATRIX SOLVER" - border_width 1 - border_color black - } - - frame { - position 0 +32 - size 42 28 - group job_parallel_env_gr - text "PARALLELIZATION ENVIRONMENT" - border_width 1 - border_color black - visible "or(*job_option parallel:on, \ - solver_multi_procs)" - } - frame { - position 15 +30 - size 42 8 - group { - layout hbox - - spacer { - stretch 1 - } - popdown { - position 15 0 - size 12 8 - text "OK" - } - spacer { - stretch 1 - } - } - } - - spacer { - spacing 2 - stretch 1 - } - } - - window { - parent mentat - origin 38 1 - size 60 119 - background_color body - border_width 1 - border_color border - buffering single - } - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_gr { - - toggle { - position 1 4 - size 42 4 - text "USE \{DDM}" - toggle "*job_option parallel:on" - help job_run_ddm_use - true_command "*job_option parallel:on" - false_command "*job_option parallel:off" - active "not(job_solver_it_ext)" - } - - frame { - position = +5 - size 42 4 - group job_ddm_use_gr - visible "*job_option parallel:on" - } -} - -group job_ddm_use_gr { - layout vbox - frame{ - position 0 0 - size 30 4 - group { - layout hbox - label { - position 0 0 - size 12 4 - text "DECOMPOSITION IN" - } - oneonly{ - position +12 = - size 8 4 - text "MARC" - oneonly "*job_option ddm_generator:fea_solver" - command "*job_option ddm_generator:fea_solver" - } - oneonly{ - position +12 = - size 8 4 - text "MENTAT" - oneonly "*job_option ddm_generator:preprocessor" - command "*job_option ddm_generator:preprocessor" - } - } - } - - frame { - position 0 +5 - size 44 8 - group job_ddm_fea_solver_gr - visible "*job_option ddm_generator:fea_solver" - } - - frame { - position = = - size 44 8 - group job_ddm_preprocessor_gr - visible "*job_option ddm_generator:preprocessor" - } - - frame{ - position 0 +5 - size 40 4 - group{ - layout hbox - text { - position 0 0 - size 22 4 - text "Single Input File" - readonly - visible "*job_option ddm_generator:fea_solver" - } - - roller { - position = = - size 22 4 - nvalues 2 - texts "MULTIPLE INPUT FILES" - "SINGLE INPUT FILE" - roller "job_option ddm_single_input" - commands "*job_option ddm_single_input:off" - "*job_option ddm_single_input:on" - visible "*job_option ddm_generator:preprocessor" - help job_run_ddm_single_input - } - - roller { - position +23 = - size 21 4 - nvalues 2 - texts "MULTIPLE POST FILES" - "SINGLE POST FILE" - roller "job_option ddm_single_post" - commands "*job_option ddm_single_post:off" - "*job_option ddm_single_post:on" - help job_run_ddm_single_post - } - } - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_fea_solver_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - help job_param - } - - text { - position +10 = - size 4 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 0 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - button { - position +18 = - size 12 4 - text "ADV. SETTINGS" - popmenu job_ddm_fea_solver_pm - } -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_ddm_fea_solver_pm { - - text "JOB PARALLELIZATION" - - group { - units 32 120 - - - label { - position 0 5 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - frame { - - position 0 +9 - size 32 76 - text "ADVANCED DECOMPOSITION IN MARC" - border_width 1 - border_color black - - group { - - label { - position 1 4 - size 16 4 - text "# DOMAINS" - help job_param - } - - text { - position +16 = - size 14 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 1 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 23 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - frame { - position 1 +5 - size 30 20 - group job_ddm_direction_gr - visible "or(*job_option ddm_method:vector, \ - *job_option ddm_method:radial, \ - *job_option ddm_method:angular)" - } - - toggle { - position 1 +21 - size 30 4 - text "DOMAIN ISLAND REMOVAL" - toggle "*job_option ddm_island_removal:on" - true_command "*job_option ddm_island_removal:on" - false_command "*job_option ddm_island_removal:off" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "GRAPH" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "COARSE" - "FINE" - help ddm_decomp_coarse_graph - rollers "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - commands "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "QUADRATIC ELEMENTS" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "GENUINE" - "LINEARIZED" - help job_run_ddm_decomp_linearized - rollers "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - commands "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - } - - label { - position 1 +5 - size 15 4 - text "ELEMENT WEIGHT FACTOR" - help job_param - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_elem_weight_factor" - command "*job_param ddm_elem_weight_factor" - help job_run_ddm_decomp_element_weight_factor - } - - toggle { - position 1 +5 - size 30 4 - text "DETECT CONTACT" - toggle "*job_option ddm_detect_contact:on" - true_command "*job_option ddm_detect_contact:on" - false_command "*job_option ddm_detect_contact:off" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - help job_run_ddm_decomp_detect_contact - } - - label { - position = +5 - size 15 4 - text "CONTACT TOLERANCE" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - command "*set_ddm_contact_tolerance" - display "job_param_value_ddm_contact_tolerance" - command "*job_param ddm_contact_tolerance" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_tolerance - } - - label { - position -15 +4 - size 15 4 - text "CONTACT CONSTR FACTOR" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_contact_constr_factor" - command "*job_param ddm_contact_constr_factor" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_constraint_factor - } - } - } - - popdown { - position 0 +77 - size 32 8 - text "OK" - } - } - mode permanent -} # job_ddm_fea_solver_pm - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_direction_gr { - - button { - position 0 0 - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "*job_option ddm_method:vector" - } - - button { - position = = - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "not(*job_option ddm_method:vector)" - } - - button { - position +15 = - size 15 4 - text "FROM / TO" - command "*job_vector_from_to ddm_sort_direction_x" - } - - text { - position -15 +4 - size 10 4 - command "*job_param ddm_sort_direction_x" - display "job_param_value_ddm_sort_direction_x" - help ddm_job_decomp_user_direction_x - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_y" - display "job_param_value_ddm_sort_direction_y" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_z" - display "job_param_value_ddm_sort_direction_z" - } - - frame { - position 0 +4 - size 30 8 - group job_ddm_sort_point_gr - visible "not(*job_option ddm_method:vector)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_sort_point_gr { - - label { - position 0 0 - size 14 4 - border_width 1 - border_color black - text "POINT ON AXIS" - } - - roller { - position +14 = - size 10 4 - nvalues 2 - texts "DEFAULT" - "USER" - roller "job_option ddm_sort_point" - commands "*job_option ddm_sort_point:default" - "*job_option ddm_sort_point:user" - } - - button { - position +10 = - size 6 4 - text "SET" - command "*job_position ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position 0 +4 - size 10 4 - command "*job_param ddm_sort_point_x" - display "job_param_value_ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_y" - display "job_param_value_ddm_sort_point_y" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_z" - display "job_param_value_ddm_sort_point_z" - visible "*job_option ddm_sort_point:user" - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_preprocessor_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - border_width 1 - border_color black - } - - integer { - position +10 = - size 4 4 - display valid_domains - } - - button { - position 0 +4 - size 30 4 - text "USER DOMAINS" - popmenu domains_pm - help job_run_ddm_user_domains - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_assem_recov_gr { - - toggle { - position 1 +4 - size 30 4 - text "MULTIPLE THREADS" - true_command "*job_option assem_recov_multi_threading:on" - false_command "*job_option assem_recov_multi_threading:off" - toggle "*job_option assem_recov_multi_threading:on" - } - - label { - position = +4 - size 12 4 - text "# THREADS" - visible "*job_option assem_recov_multi_threading:on" - } - - text { - position +12 = - size 4 4 - display "job_param_value_assem_recov_nthreads" - command "*job_param assem_recov_nthreads" - visible "*job_option assem_recov_multi_threading:on" - } - - label { - position +4 = - size 10 4 - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - } - - display { - position +12 = - size 4 4 - display "job_assem_recov_nthreads_dom" - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - } - spacer{ - stretch 2 - } - -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_matrix_solver_gr { - layout vbox - frame { - position 1 0 - size 36 31 - group { - layout hbox - label { - position 3 4 - size 12 4 - text "SOLUTION" - border_width 1 - border_color black - } - oneonly { - position +12 = - size 12 4 - text "SYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_off" - command "*job_option solver_nonsym:off" - } - oneonly { - position +12 = - size 12 4 - text "NONSYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_on" - command "*job_option solver_nonsym:on" - } - spacer { - stretch 1 - } - } - } - - frame { - position 1 +5 - size 42 23 - group matrix_solver_gr - help job_param_solver - } - - frame { - position +1 = - size 42 4 - group job_run_solver_ddm_opts_gr - visible "*job_option parallel:on" - } - - frame { - position 1 +23 - size 42 8 - group job_solver_multi_procs_gr - visible solver_allows_multi_procs - } - - frame { - position = = - size 42 8 - group job_solver_multi_threads_gr - visible solver_allows_multi_threads - } - - frame { - position 1 +9 - size 42 8 - group job_solver_gpu_gr - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_run_solver_ddm_opts_gr { - - button { - position 0 0 - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options -# see also job_common.ms! - visible "not(or(job_solver_it_sparse, \ - job_solver_it_ext, \ - job_solver_mixed_direct_iterative, \ - job_solver_pardiso,\ - job_solver_mumps))" - } - button { - position = = - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options_mumps - visible "job_solver_mumps" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_gr { - frame { - position 0 0 - size 42 8 - group job_solver_multi_procs_parallel_off_gr - visible "*job_option parallel:off" - } - - frame { - position = = - size 42 8 - group job_solver_multi_procs_parallel_on_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - true_command "*job_option nsolver_procs_serial:on" - false_command "*job_option nsolver_procs_serial:off" - toggle "*job_option nsolver_procs_serial:on" - help job_run_multithreading - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - visible "*job_option nsolver_procs_serial:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - visible "*job_option nsolver_procs_serial:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - border_width 1 - border_color black - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - help job_run_multithreading - rollers "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_nsolver_procs_ddm_automatic_gr - visible "*job_option nsolver_procs_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_nsolver_procs_ddm_user_gr - visible "*job_option nsolver_procs_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - } -} - -group job_solver_multi_threads_gr { - frame { - position 0 0 - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_off_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:off)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_on_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:on)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_pardiso_parallel_off_gr - visible "and(job_solver_pardiso,*job_option parallel:off)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_pardiso_parallel_on_gr - visible "and(job_solver_pardiso,*job_option parallel:on)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_it_ext_off_gr - visible "and(job_solver_it_ext,*job_option parallel:off)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option mfront_sparse_multi_threading:on" - true_command "*job_option mfront_sparse_multi_threading:on" - false_command "*job_option mfront_sparse_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option mfront_sparse_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option mfront_sparse_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +30 0 - size 12 4 - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - } - - display { - position +12 0 - size 4 4 - display "job_mfront_sparse_nthreads_dom" - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - } - - label { - position 0 +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_automatic_gr - visible "*job_option mfront_sparse_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_user_gr - visible "*job_option mfront_sparse_multi_threading_ddm:user" - } -} -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - - - -#-------------------------------------------------------------------------------------------------- -group job_solver_gpu_gr { - - toggle { - position 0 0 - size 30 4 - text "USE \{GPU(s)}" - toggle "*job_option solver_use_gpu:on" - true_command "*job_option solver_use_gpu:on" - false_command "*job_option solver_use_gpu:off" - help job_solver_gpu - } - frame{ - position 0 +4 - size 28 4 - group{ - layout hbox - - label { - position 0 0 - size 16 4 - text "\{GPU} SELECTION" - border_width 1 - border_color black - visible "*job_option solver_use_gpu:on" - } - - roller { - position +16 = - size 12 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - rollers "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - visible "*job_option solver_use_gpu:on" - help job_solver_gpu - } - - text { - position +12 = - size 12 4 - display job_solver_gpus - command "*clear_job_solver_gpus *job_solver_gpus" - visible "and(*job_option solver_use_gpu:on,*job_option solver_gpus:user)" - } - spacer { - stretch 1 - } - } - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option pardiso_multi_threading:on" - true_command "*job_option pardiso_multi_threading:on" - false_command "*job_option pardiso_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option pardiso_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option pardiso_multi_threading:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position = +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_pardiso_multi_threads_ddm_automatic_gr - visible "*job_option pardiso_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_pardiso_multi_threads_ddm_user_gr - visible "*job_option pardiso_multi_threading_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_it_ext_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option it_ext_multi_threading:on" - true_command "*job_option it_ext_multi_threading:on" - false_command "*job_option it_ext_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option it_ext_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option it_ext_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_gr { - - frame{ - position 0 +4 - size 40 4 - group{ - layout hbox - label{ - position 0 0 - size 8 4 - text "SETUP" - help job_run_ddm_setup - } - oneonly { - position +12 = - size 12 4 - text "SINGLE MACHINE" - oneonly "*job_option parallel_setup:single" - command "*job_option parallel_setup:single" - help job_run_ddm_setup - } - oneonly { - position +8 = - size 12 4 - text "NETWORK" - oneonly "*job_option parallel_setup:network" - command "*job_option parallel_setup:network" - help job_run_ddm_setup - } - - spacer { - stretch 1 - } - } - } - - - frame { - position +1 +5 - size 40 16 - group job_parallel_env_network_gr - visible "*job_option parallel_setup:network" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_gr { - - button { - position 0 0 - size 28 4 - text "HOST FILE" - browser host_file_browser - settext $host_file_browser_label "SELECT HOST FILE" - set $host_file_browser_command "*job_host_file" - help job_host_file - } - - button { - position +28 = - size 8 4 - text "EDIT" - command "*job_edit_host_file" - help job_edit_host_file - visible job_host_file - } - - button { - position +8 = - size 8 4 - text "CLEAR" - command "*job_clear_host_file" - help job_clear_host_file - visible job_host_file - } - - display { - position 0 +4 - size 44 4 - display job_host_file - } - - frame { - position 0 +5 - size 44 9 - group job_parallel_env_network_ddm_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_ddm_gr { - - toggle { - position 0 0 - size 22 4 - text "COPY INPUT FILE" - toggle "*job_option copy_input_file:on" - true_command "*job_option copy_input_file:on" - false_command "*job_option copy_input_file:off" - help job_host_copy_inputfile - } - - toggle { - position +23 = - size 21 4 - text "COPY POST FILE" - toggle "*job_option copy_post_file:on" - true_command "*job_option copy_post_file:on" - false_command "*job_option copy_post_file:off" - help job_host_copy_inputfile - } - - label { - position 0 +5 - size 10 4 - text "HOSTS" - border_width 1 - border_color black - visible job_usersub_file - } - - roller { - position +10 = - size 18 4 - nvalues 2 - texts "COMPATIBLE" - "INCOMPATIBLE" - roller "job_option network_hosts" - commands "*job_option network_hosts:compatible" - "*job_option network_hosts:incompatible" - help job_host_comp - visible job_usersub_file - } -} - - -#endif diff --git a/installation/mods_MarcMentat/2018/Mentat_menus/job_run.ms.original b/installation/mods_MarcMentat/2018/Mentat_menus/job_run.ms.original deleted file mode 100644 index 428b261d3..000000000 --- a/installation/mods_MarcMentat/2018/Mentat_menus/job_run.ms.original +++ /dev/null @@ -1,2560 +0,0 @@ -#ifndef AUTOFORGE -popmenu job_title_pm file jobs.ms -popdown job_title_ok file jobs.ms - -group user_domains_gr file domain_decomposition.ms -group user_domains_generate_gr file domain_decomposition.ms -group user_domains_tail_gr file domain_decomposition.ms -group matrix_solver_gr file job_common.ms -popmenu ddm_options file job_common.ms - -browser edit_browser file file.ms -browser directory_browser file file.ms -screen domains file domain_decomposition.ms - - - - browser usersub_file_browser { - position 0 0 - size 82 72 - text "$usersub_file_browser_label" ($usersub_file_browser_label) - filter "*.f *.F *.f90 *.F90" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$usersub_file_browser_command" ($usersub_file_browser_command) - } - - - - browser host_file_browser { - position 0 0 - size 82 72 - text "$host_file_browser_label" ($host_file_browser_label) - filter "*" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$host_file_browser_command" ($host_file_browser_command) - } - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_popmenu { - - text "RUN JOB" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - button { - position 1 9 - size 24 4 - text "USER SUBROUTINE FILE" - browser usersub_file_browser - settext $usersub_file_browser_label "SELECT USER SUBROUTINE FILE" - set $usersub_file_browser_command "*job_usersub_file" - help job_usersub_file - } - - toggle { - position +26 = - size 22 4 - text "SELECTED USER SUBS" - toggle job_usersubs - help job_run_seluser - visible job_usersubs - popmenu job_usersub_pm - } - - display { - position 1 +4 - size 50 4 - display job_usersub_file - } - - button { - position 1 +4 - size 12 4 - text "EDIT" - command "*job_edit_usersub_file" - visible job_usersub_file - } - - button { - position +12 = - size 12 4 - text "CLEAR" - command "*job_clear_usersub_file" - visible job_usersub_file - } - - roller { - position +12 = - size 26 4 - nvalues 3 - texts "COMPILE / NO SAVE" - "COMPILE AND SAVE" - "RUN SAVED EXECUTABLE" - help job_run_compile - roller "job_option user_source" - visible job_usersub_file - commands "*job_option user_source:compile_nosave" - "*job_option user_source:compile_save" - "*job_option user_source:run_saved" - } - - button { - position 1 +6 - size 24 4 - text "SOLVER/PARALLELIZATION" - help job_run_parallel - popmenu job_run_parallelization_pm - set $popname2 "job_run_parallelization_pm" - } - frame { - position 1 +4 - size 48 16 - border_width 1 - border_color black - - group{ - layout hbox - frame { - position 0 0 - size 24 16 - group { - layout vbox - - display { - position 0 0 - size 24 4 - display job_solver_solution - } - - display { - position = +4 - size 24 4 - display job_solver_type - } - spacer { - stretch 1 - } - - } - } - - frame { - position +22 = - size 24 16 - border_width 1 - border_color black - - group { - #layout vbox - display { - position = +4 - size 24 4 - display job_ddm_domains - } - - display { - position = +4 - size 24 4 - display job_assem_recov_nthreads - } - - display { - position = +4 - size 24 4 - display job_solver_procs - visible solver_allows_multi_procs - } - - display { - position = = - size 24 4 - display job_solver_threads - visible "and(solver_allows_multi_threads,\ - not(and(job_solver_mfront_sparse,\ - *job_option parallel:on)))" - } - - display { - position = +4 - size 24 4 - display job_solver_gpu - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } - } - } - } - } - - button { - position 1 +18 - size 8 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - -# see also job_common.ms -# see also the ADVANCED JOB SUBMISSION popmenu in this file - - label { - position +10 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - button { - position +20 = - size 13 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position 1 +6 - size 16 6 - text "SUBMIT (1)" - command "*submit_job 1 *monitor_job" - } - - button { - position +16 = - size 34 6 - text "ADVANCED JOB SUBMISSION" - popmenu job_submit_adv_pm - } - - button { - position 1 +6 - size 16 6 - text "UPDATE" - command "*update_job" - } - - button { - position +16 = - size 16 6 - text "MONITOR" - command "*monitor_job" - } - - button { - position +16 = - size 18 6 - text "KILL" - command "*kill_job *monitor_job" - } - - label { - position 1 +7 - size 32 4 - text "STATUS" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_status" - } - - label { - position -32 +4 - size 32 4 - text "CURRENT INCREMENT (CYCLE)" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_increment" - } - - label { - position -32 +4 - size 32 4 - text "SINGULARITY RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_singularity_ratio" - } - - label { - position -32 +4 - size 32 4 - text "CONVERGENCE RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_convergence_ratio" - } - - label { - position 1 +4 - size 32 4 - text "ANALYSIS TIME" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_analysis_time" - } - - label { - position -32 +4 - size 32 4 - text "WALL TIME" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_time" - } - - frame { - position 1 +4 - size 50 8 - - group { - - frame { - position 0 0 - size 50 8 - text "TOTAL" - border_width 1 - border_color black - group { - - label { - position +6 = - size 13 4 - text "CYCLES" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_cycles" - border_width 1 - border_color black - } - - label { - position -13 +4 - size 13 4 - text "SEPARATIONS" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_separations" - border_width 1 - border_color black - } - - label { - position +10 -4 - size 11 4 - text "CUT BACKS" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_cut_backs" - border_width 1 - border_color black - } - - label { - position -11 +4 - size 11 4 - text "REMESHES" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_remeshes" - border_width 1 - border_color black - } - } - } - } - } - - label { - position 1 +8 - size 19 4 - text "EXIT NUMBER" - border_width 1 - border_color black - } - - integer { - position +19 = - size 10 4 - display "job_exit" - } - - button { - position +10 = - size 21 4 - text "EXIT MESSAGE" - popmenu job_exit_msg_pm - help exit_message - } - - label { - position 1 +6 - size 7 4 - text "EDIT" - border_width 1 - border_color black - } - - button { - position +7 = - size 12 4 - text "OUTPUT FILE" - command "*job_edit_output" - } - - button { - position +12 = - size 9 4 - text "LOG FILE" - command "*job_edit_log_file" - } - - button { - position +9 = - size 12 4 - text "STATUS FILE" - command "*job_edit_status_file" - } - - button { - position +12 = - size 10 4 - text "ANY FILE" - settext $edit_browser_label "EDIT FILE" - set $edit_browser_command "*edit_file" - browser edit_browser - help edit_file - } - - popdown { - position 1 +6 - size 32 4 - text "OPEN POST FILE (MODEL PLOT RESULTS MENU)" - command "@popdown(job_properties_pm) @main(results) @popup(modelplot_pm) *post_open_default" - } - - button { - position 1 +6 - size 12 8 - text "RESET" - command "*job_submit_reset" - } - - popdown { - position +38 = - size 12 8 - text "OK" - } - } - - window job_run_wi { - parent mentat - origin 35 1 - size 52 115 - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_usersub_pm { - - text "CURRENTLY SELECTED USER SUBROUTINES" - - group { - - - display { - position 1 +5 - size 64 86 - display "job_usersubs" - } - - popdown { - position 27 +88 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 66 102 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_submit_adv_pm { - - text "ADVANCED JOB SUBMISSION" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - label { - position 1 9 - size 19 4 - text "INITIAL ALLOCATION" - border_width 1 - border_color black - } - label { - position +19 = - size 15 4 - text "GENERAL MEMORY" - help job_param_general_init_allocation - } - text { - position +15 = - size 10 4 - display "job_param_value_general_init_allocation" - command "*job_param general_init_allocation" - help job_param_general_init_allocation - } - - label { - position +10 = - size 4 4 - text "MB" - border_width 1 - border_color black - } - - toggle { - position 1 +5 - size 32 4 - text "OUT-OF-CORE ELEMENT STORAGE" - help job_param_elsto - toggle "*job_option elsto:on" - true_command "*job_option elsto:on" - false_command "*job_option elsto:off" - } - - toggle { - position 1 +4 - size 32 4 - text "OUT-OF-CORE INCREMENTAL BACKUP" - help job_param_inc_backup_storage - toggle "*job_option inc_backup_storage:out_of_core" - true_command "*job_option inc_backup_storage:out_of_core" - false_command "*job_option inc_backup_storage:in_core" - } - - toggle { - position +34 = - size 14 4 - text "CHECK SIZES" - help job_run_check - toggle "*job_option check:on" - true_command "*job_option check:on" - false_command "*job_option check:off" - } - - frame { - position 1 +6 - size 48 12 - text "MARC INPUT FILE" - border_width 1 - border_color black - - group { - - label { - position 0 4 - size 9 4 - text "VERSION" - border_width 1 - border_color black - } - - roller { - position +9 = - size 14 4 - nvalues 25 - nvisible 25 - texts "DEFAULT" -#if 0 - "2018" -#endif - "2017.1" - "2017" - "2016" - "2015" - "2014.2" - "2014.1" - "2014" - "2013.1" - "2013" - "2012" - "2011" - "2010.2" - "2010" - "2008" - "2007" - "2005R3" - "2005" - "2003" - "2001" - "2000" -#if 0 - "8" -#endif - "K7" - "K6.2" - "K5" - "K4" - help job_param_version - rollers "job_input_version_default" -#if 0 - "job_input_version_2018" -#endif - "job_input_version_2017.1" - "job_input_version_2017" - "job_input_version_2016" - "job_input_version_2015" - "job_input_version_2014.2" - "job_input_version_2014.1" - "job_input_version_2014" - "job_input_version_2013.1" - "job_input_version_2013" - "job_input_version_2012" - "job_input_version_2011" - "job_input_version_2010.2" - "job_input_version_2010" - "job_input_version_2008" - "job_input_version_2007" - "job_input_version_2005r3" - "job_input_version_2005" - "job_input_version_2003" - "job_input_version_2001" - "job_input_version_2000" -#if 0 - "job_input_version_8" -#endif - "job_input_version_k7" - "job_input_version_k6" - "job_input_version_k5" - "job_input_version_k4" - commands "*job_option version:default" -#if 0 - "*job_option version:2018" -#endif - "*job_option version:2017.1" - "*job_option version:2017" - "*job_option version:2016" - "*job_option version:2015" - "*job_option version:2014.2" - "*job_option version:2014.1" - "*job_option version:2014" - "*job_option version:2013.1" - "*job_option version:2013" - "*job_option version:2012" - "*job_option version:2011" - "*job_option version:2010.2" - "*job_option version:2010" - "*job_option version:2008" - "*job_option version:2007" - "*job_option version:2005r3" - "*job_option version:2005" - "*job_option version:2003" - "*job_option version:2001" - "*job_option version:2000" -#if 0 - "*job_option version:8" -#endif - "*job_option version:k7" - "*job_option version:k6" - "*job_option version:k5" - "*job_option version:k4" - visibles "job_allows_input_version_default" -#if 0 - "job_allows_input_version_2018" -#endif - "job_allows_input_version_2017.1" - "job_allows_input_version_2017" - "job_allows_input_version_2016" - "job_allows_input_version_2015" - "job_allows_input_version_2014.2" - "job_allows_input_version_2014.1" - "job_allows_input_version_2014" - "job_allows_input_version_2013.1" - "job_allows_input_version_2013" - "job_allows_input_version_2012" - "job_allows_input_version_2011" - "job_allows_input_version_2010.2" - "job_allows_input_version_2010" - "job_allows_input_version_2008" - "job_allows_input_version_2007" - "job_allows_input_version_2005r3" - "job_allows_input_version_2005" - "job_allows_input_version_2003" - "job_allows_input_version_2001" - "job_allows_input_version_2000" -#if 0 - "job_allows_input_version_8" -#endif - "job_allows_input_version_k7" - "job_allows_input_version_k6" - "job_allows_input_version_k5" - "job_allows_input_version_k4" - } - -# see also job_common.ms -# see also the RUN JOB popmenu in this file - - label { - position +14 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - toggle { - position 0 +4 - size 24 4 - text "EXTENDED PRECISION" - help job_run_precision - toggle "*job_option inp_file_prec:extended" - true_command "*job_option inp_file_prec:extended" - false_command "*job_option inp_file_prec:normal" - } - toggle { - position +24 = - size 24 4 - text "INCLUDE UNUSED TABLES" - toggle "*job_option input_file_tables:all" - true_command "*job_option input_file_tables:all" - false_command "*job_option input_file_tables:used" - } - } - } - - button { - position 1 +14 - size 24 4 - text "SCRATCH DIRECTORY" - settext $directory_browser_label "JOB SCRATCH DIRECTORY" - set $directory_browser_command "*job_scratch_directory" - browser directory_browser - help job_scratch_directory - } - - button { - position +24 = - size 24 4 - text "CLEAR" - command "*job_clear_scratch_directory" - visible job_scratch_directory - } - - text { - position 1 +4 - size 48 4 - display job_scratch_dir - command "*job_scratch_directory" - } - -#ifdef DCOM - toggle { - position 1 +6 - size 8 4 - text "\{DCOM}" - toggle "*job_option dcom:on" - help job_run_dcom - true_command "*job_option dcom:on" - false_command "*job_option dcom:off" - visible win32_available - } - - button { - position +8 = - size 12 4 - text "HOSTNAME" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } - - text job_dcom_hostname { - position +12 = - size 28 4 - display "job_dcom_hostname" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } -#endif - - button { - position 1 +6 - size 24 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - - button { - position +24 = - size 24 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position +4 +6 - size 20 4 - text "WRITE INPUT FILE" - command "*job_write_input" - } - - button { - position = +4 - size 20 4 - text "EDIT INPUT FILE" - command "*job_edit_input" - } - - popdown { - position 1 +5 - size 20 6 - text "SUBMIT 1" - command "*submit_job 1 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 1" - command "*execute_job 1 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 2" - command "*submit_job 2 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 2" - command "*execute_job 2 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 3" - command "*submit_job 3 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 3" - command "*execute_job 3 *monitor_job" - } - - popdown { - position 19 +8 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 -#ifdef DCOM - size 50 100 -#else - size 50 94 -#endif - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_exit_msg_pm { - - text "EXIT MESSAGE" - - group { - - - - text { - position 1 5 - size 84 74 - multiline - readonly - display "job_exit_msg" - } - - popdown { - position 37 +76 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 86 90 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_parallelization_pm { - - text "SOLVER/PARALLELIZATION" - - group { - layout vbox - frame { - position 0 0 - size 42 8 - group { - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 36 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 36 4 - display job_class_label - } - } - } - frame { - position 0 8 - size 42 20 - group job_ddm_gr - text "DOMAIN DECOMPOSITION" - border_width 1 - border_color black - } - - frame { - position 0 +20 - size 42 13 - group job_assem_recov_gr - text "ASSEMBLY AND RECOVERY" - border_width 1 - border_color black - } - - frame { - position 0 +14 - size 42 31 - group job_parallel_matrix_solver_gr - text "MATRIX SOLVER" - border_width 1 - border_color black - } - - frame { - position 0 +32 - size 42 28 - group job_parallel_env_gr - text "PARALLELIZATION ENVIRONMENT" - border_width 1 - border_color black - visible "or(*job_option parallel:on, \ - solver_multi_procs)" - } - frame { - position 15 +30 - size 42 8 - group { - layout hbox - - spacer { - stretch 1 - } - popdown { - position 15 0 - size 12 8 - text "OK" - } - spacer { - stretch 1 - } - } - } - - spacer { - spacing 2 - stretch 1 - } - } - - window { - parent mentat - origin 38 1 - size 60 119 - background_color body - border_width 1 - border_color border - buffering single - } - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_gr { - - toggle { - position 1 4 - size 42 4 - text "USE \{DDM}" - toggle "*job_option parallel:on" - help job_run_ddm_use - true_command "*job_option parallel:on" - false_command "*job_option parallel:off" - active "not(job_solver_it_ext)" - } - - frame { - position = +5 - size 42 4 - group job_ddm_use_gr - visible "*job_option parallel:on" - } -} - -group job_ddm_use_gr { - layout vbox - frame{ - position 0 0 - size 30 4 - group { - layout hbox - label { - position 0 0 - size 12 4 - text "DECOMPOSITION IN" - } - oneonly{ - position +12 = - size 8 4 - text "MARC" - oneonly "*job_option ddm_generator:fea_solver" - command "*job_option ddm_generator:fea_solver" - } - oneonly{ - position +12 = - size 8 4 - text "MENTAT" - oneonly "*job_option ddm_generator:preprocessor" - command "*job_option ddm_generator:preprocessor" - } - } - } - - frame { - position 0 +5 - size 44 8 - group job_ddm_fea_solver_gr - visible "*job_option ddm_generator:fea_solver" - } - - frame { - position = = - size 44 8 - group job_ddm_preprocessor_gr - visible "*job_option ddm_generator:preprocessor" - } - - frame{ - position 0 +5 - size 40 4 - group{ - layout hbox - text { - position 0 0 - size 22 4 - text "Single Input File" - readonly - visible "*job_option ddm_generator:fea_solver" - } - - roller { - position = = - size 22 4 - nvalues 2 - texts "MULTIPLE INPUT FILES" - "SINGLE INPUT FILE" - roller "job_option ddm_single_input" - commands "*job_option ddm_single_input:off" - "*job_option ddm_single_input:on" - visible "*job_option ddm_generator:preprocessor" - help job_run_ddm_single_input - } - - roller { - position +23 = - size 21 4 - nvalues 2 - texts "MULTIPLE POST FILES" - "SINGLE POST FILE" - roller "job_option ddm_single_post" - commands "*job_option ddm_single_post:off" - "*job_option ddm_single_post:on" - help job_run_ddm_single_post - } - } - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_fea_solver_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - help job_param - } - - text { - position +10 = - size 4 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 0 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - button { - position +18 = - size 12 4 - text "ADV. SETTINGS" - popmenu job_ddm_fea_solver_pm - } -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_ddm_fea_solver_pm { - - text "JOB PARALLELIZATION" - - group { - units 32 120 - - - label { - position 0 5 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - frame { - - position 0 +9 - size 32 76 - text "ADVANCED DECOMPOSITION IN MARC" - border_width 1 - border_color black - - group { - - label { - position 1 4 - size 16 4 - text "# DOMAINS" - help job_param - } - - text { - position +16 = - size 14 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 1 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 23 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - frame { - position 1 +5 - size 30 20 - group job_ddm_direction_gr - visible "or(*job_option ddm_method:vector, \ - *job_option ddm_method:radial, \ - *job_option ddm_method:angular)" - } - - toggle { - position 1 +21 - size 30 4 - text "DOMAIN ISLAND REMOVAL" - toggle "*job_option ddm_island_removal:on" - true_command "*job_option ddm_island_removal:on" - false_command "*job_option ddm_island_removal:off" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "GRAPH" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "COARSE" - "FINE" - help ddm_decomp_coarse_graph - rollers "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - commands "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "QUADRATIC ELEMENTS" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "GENUINE" - "LINEARIZED" - help job_run_ddm_decomp_linearized - rollers "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - commands "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - } - - label { - position 1 +5 - size 15 4 - text "ELEMENT WEIGHT FACTOR" - help job_param - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_elem_weight_factor" - command "*job_param ddm_elem_weight_factor" - help job_run_ddm_decomp_element_weight_factor - } - - toggle { - position 1 +5 - size 30 4 - text "DETECT CONTACT" - toggle "*job_option ddm_detect_contact:on" - true_command "*job_option ddm_detect_contact:on" - false_command "*job_option ddm_detect_contact:off" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - help job_run_ddm_decomp_detect_contact - } - - label { - position = +5 - size 15 4 - text "CONTACT TOLERANCE" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - command "*set_ddm_contact_tolerance" - display "job_param_value_ddm_contact_tolerance" - command "*job_param ddm_contact_tolerance" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_tolerance - } - - label { - position -15 +4 - size 15 4 - text "CONTACT CONSTR FACTOR" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_contact_constr_factor" - command "*job_param ddm_contact_constr_factor" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_constraint_factor - } - } - } - - popdown { - position 0 +77 - size 32 8 - text "OK" - } - } - mode permanent -} # job_ddm_fea_solver_pm - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_direction_gr { - - button { - position 0 0 - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "*job_option ddm_method:vector" - } - - button { - position = = - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "not(*job_option ddm_method:vector)" - } - - button { - position +15 = - size 15 4 - text "FROM / TO" - command "*job_vector_from_to ddm_sort_direction_x" - } - - text { - position -15 +4 - size 10 4 - command "*job_param ddm_sort_direction_x" - display "job_param_value_ddm_sort_direction_x" - help ddm_job_decomp_user_direction_x - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_y" - display "job_param_value_ddm_sort_direction_y" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_z" - display "job_param_value_ddm_sort_direction_z" - } - - frame { - position 0 +4 - size 30 8 - group job_ddm_sort_point_gr - visible "not(*job_option ddm_method:vector)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_sort_point_gr { - - label { - position 0 0 - size 14 4 - border_width 1 - border_color black - text "POINT ON AXIS" - } - - roller { - position +14 = - size 10 4 - nvalues 2 - texts "DEFAULT" - "USER" - roller "job_option ddm_sort_point" - commands "*job_option ddm_sort_point:default" - "*job_option ddm_sort_point:user" - } - - button { - position +10 = - size 6 4 - text "SET" - command "*job_position ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position 0 +4 - size 10 4 - command "*job_param ddm_sort_point_x" - display "job_param_value_ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_y" - display "job_param_value_ddm_sort_point_y" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_z" - display "job_param_value_ddm_sort_point_z" - visible "*job_option ddm_sort_point:user" - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_preprocessor_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - border_width 1 - border_color black - } - - integer { - position +10 = - size 4 4 - display valid_domains - } - - button { - position 0 +4 - size 30 4 - text "USER DOMAINS" - popmenu domains_pm - help job_run_ddm_user_domains - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_assem_recov_gr { - - toggle { - position 1 +4 - size 30 4 - text "MULTIPLE THREADS" - true_command "*job_option assem_recov_multi_threading:on" - false_command "*job_option assem_recov_multi_threading:off" - toggle "*job_option assem_recov_multi_threading:on" - } - - label { - position = +4 - size 12 4 - text "# THREADS" - visible "*job_option assem_recov_multi_threading:on" - } - - text { - position +12 = - size 4 4 - display "job_param_value_assem_recov_nthreads" - command "*job_param assem_recov_nthreads" - visible "*job_option assem_recov_multi_threading:on" - } - - label { - position +4 = - size 10 4 - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - } - - display { - position +12 = - size 4 4 - display "job_assem_recov_nthreads_dom" - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - } - spacer{ - stretch 2 - } - -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_matrix_solver_gr { - layout vbox - frame { - position 1 0 - size 36 31 - group { - layout hbox - label { - position 3 4 - size 12 4 - text "SOLUTION" - border_width 1 - border_color black - } - oneonly { - position +12 = - size 12 4 - text "SYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_off" - command "*job_option solver_nonsym:off" - } - oneonly { - position +12 = - size 12 4 - text "NONSYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_on" - command "*job_option solver_nonsym:on" - } - spacer { - stretch 1 - } - } - } - - frame { - position 1 +5 - size 42 23 - group matrix_solver_gr - help job_param_solver - } - - frame { - position +1 = - size 42 4 - group job_run_solver_ddm_opts_gr - visible "*job_option parallel:on" - } - - frame { - position 1 +23 - size 42 8 - group job_solver_multi_procs_gr - visible solver_allows_multi_procs - } - - frame { - position = = - size 42 8 - group job_solver_multi_threads_gr - visible solver_allows_multi_threads - } - - frame { - position 1 +9 - size 42 8 - group job_solver_gpu_gr - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_run_solver_ddm_opts_gr { - - button { - position 0 0 - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options -# see also job_common.ms! - visible "not(or(job_solver_it_sparse, \ - job_solver_it_ext, \ - job_solver_mixed_direct_iterative, \ - job_solver_pardiso,\ - job_solver_mumps))" - } - button { - position = = - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options_mumps - visible "job_solver_mumps" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_gr { - frame { - position 0 0 - size 42 8 - group job_solver_multi_procs_parallel_off_gr - visible "*job_option parallel:off" - } - - frame { - position = = - size 42 8 - group job_solver_multi_procs_parallel_on_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - true_command "*job_option nsolver_procs_serial:on" - false_command "*job_option nsolver_procs_serial:off" - toggle "*job_option nsolver_procs_serial:on" - help job_run_multithreading - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - visible "*job_option nsolver_procs_serial:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - visible "*job_option nsolver_procs_serial:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - border_width 1 - border_color black - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - help job_run_multithreading - rollers "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_nsolver_procs_ddm_automatic_gr - visible "*job_option nsolver_procs_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_nsolver_procs_ddm_user_gr - visible "*job_option nsolver_procs_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - } -} - -group job_solver_multi_threads_gr { - frame { - position 0 0 - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_off_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:off)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_on_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:on)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_pardiso_parallel_off_gr - visible "and(job_solver_pardiso,*job_option parallel:off)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_pardiso_parallel_on_gr - visible "and(job_solver_pardiso,*job_option parallel:on)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_it_ext_off_gr - visible "and(job_solver_it_ext,*job_option parallel:off)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option mfront_sparse_multi_threading:on" - true_command "*job_option mfront_sparse_multi_threading:on" - false_command "*job_option mfront_sparse_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option mfront_sparse_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option mfront_sparse_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +30 0 - size 12 4 - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - } - - display { - position +12 0 - size 4 4 - display "job_mfront_sparse_nthreads_dom" - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - } - - label { - position 0 +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_automatic_gr - visible "*job_option mfront_sparse_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_user_gr - visible "*job_option mfront_sparse_multi_threading_ddm:user" - } -} -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - - - -#-------------------------------------------------------------------------------------------------- -group job_solver_gpu_gr { - - toggle { - position 0 0 - size 30 4 - text "USE \{GPU(s)}" - toggle "*job_option solver_use_gpu:on" - true_command "*job_option solver_use_gpu:on" - false_command "*job_option solver_use_gpu:off" - help job_solver_gpu - } - frame{ - position 0 +4 - size 28 4 - group{ - layout hbox - - label { - position 0 0 - size 16 4 - text "\{GPU} SELECTION" - border_width 1 - border_color black - visible "*job_option solver_use_gpu:on" - } - - roller { - position +16 = - size 12 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - rollers "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - visible "*job_option solver_use_gpu:on" - help job_solver_gpu - } - - text { - position +12 = - size 12 4 - display job_solver_gpus - command "*clear_job_solver_gpus *job_solver_gpus" - visible "and(*job_option solver_use_gpu:on,*job_option solver_gpus:user)" - } - spacer { - stretch 1 - } - } - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option pardiso_multi_threading:on" - true_command "*job_option pardiso_multi_threading:on" - false_command "*job_option pardiso_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option pardiso_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option pardiso_multi_threading:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position = +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_pardiso_multi_threads_ddm_automatic_gr - visible "*job_option pardiso_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_pardiso_multi_threads_ddm_user_gr - visible "*job_option pardiso_multi_threading_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_it_ext_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option it_ext_multi_threading:on" - true_command "*job_option it_ext_multi_threading:on" - false_command "*job_option it_ext_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option it_ext_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option it_ext_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_gr { - - frame{ - position 0 +4 - size 40 4 - group{ - layout hbox - label{ - position 0 0 - size 8 4 - text "SETUP" - help job_run_ddm_setup - } - oneonly { - position +12 = - size 12 4 - text "SINGLE MACHINE" - oneonly "*job_option parallel_setup:single" - command "*job_option parallel_setup:single" - help job_run_ddm_setup - } - oneonly { - position +8 = - size 12 4 - text "NETWORK" - oneonly "*job_option parallel_setup:network" - command "*job_option parallel_setup:network" - help job_run_ddm_setup - } - - spacer { - stretch 1 - } - } - } - - - frame { - position +1 +5 - size 40 16 - group job_parallel_env_network_gr - visible "*job_option parallel_setup:network" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_gr { - - button { - position 0 0 - size 28 4 - text "HOST FILE" - browser host_file_browser - settext $host_file_browser_label "SELECT HOST FILE" - set $host_file_browser_command "*job_host_file" - help job_host_file - } - - button { - position +28 = - size 8 4 - text "EDIT" - command "*job_edit_host_file" - help job_edit_host_file - visible job_host_file - } - - button { - position +8 = - size 8 4 - text "CLEAR" - command "*job_clear_host_file" - help job_clear_host_file - visible job_host_file - } - - display { - position 0 +4 - size 44 4 - display job_host_file - } - - frame { - position 0 +5 - size 44 9 - group job_parallel_env_network_ddm_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_ddm_gr { - - toggle { - position 0 0 - size 22 4 - text "COPY INPUT FILE" - toggle "*job_option copy_input_file:on" - true_command "*job_option copy_input_file:on" - false_command "*job_option copy_input_file:off" - help job_host_copy_inputfile - } - - toggle { - position +23 = - size 21 4 - text "COPY POST FILE" - toggle "*job_option copy_post_file:on" - true_command "*job_option copy_post_file:on" - false_command "*job_option copy_post_file:off" - help job_host_copy_inputfile - } - - label { - position 0 +5 - size 10 4 - text "HOSTS" - border_width 1 - border_color black - visible job_usersub_file - } - - roller { - position +10 = - size 18 4 - nvalues 2 - texts "COMPATIBLE" - "INCOMPATIBLE" - roller "job_option network_hosts" - commands "*job_option network_hosts:compatible" - "*job_option network_hosts:incompatible" - help job_host_comp - visible job_usersub_file - } -} - - -#endif diff --git a/installation/mods_MarcMentat/2019.1/Marc_tools/comp_damask_hmp b/installation/mods_MarcMentat/2019.1/Marc_tools/comp_damask_hmp deleted file mode 100644 index de6fce745..000000000 --- a/installation/mods_MarcMentat/2019.1/Marc_tools/comp_damask_hmp +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -usernoext=$user -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - -# add BLAS options for linking - BLAS="%BLAS%" - -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user on host `hostname`" -echo "program: $program" - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$usernoext.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $BLAS \ - $SYSLIBS || \ - { - echo "$0: link failed for $usernoext.o on host `hostname`" - exit 1 - } - /bin/rm $userobj - /bin/rm $DIRJOB/*.mod - /bin/rm $DIRJOB/*.smod diff --git a/installation/mods_MarcMentat/2019.1/Marc_tools/comp_damask_lmp b/installation/mods_MarcMentat/2019.1/Marc_tools/comp_damask_lmp deleted file mode 100644 index 6d063adf3..000000000 --- a/installation/mods_MarcMentat/2019.1/Marc_tools/comp_damask_lmp +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -usernoext=$user -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - -# add BLAS options for linking - BLAS="%BLAS%" - -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user on host `hostname`" -echo "program: $program" - $DFORTRANLOWMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$usernoext.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $BLAS \ - $SYSLIBS || \ - { - echo "$0: link failed for $usernoext.o on host `hostname`" - exit 1 - } - /bin/rm $userobj - /bin/rm $DIRJOB/*.mod - /bin/rm $DIRJOB/*.smod diff --git a/installation/mods_MarcMentat/2019.1/Marc_tools/comp_damask_mp b/installation/mods_MarcMentat/2019.1/Marc_tools/comp_damask_mp deleted file mode 100644 index 871b8a449..000000000 --- a/installation/mods_MarcMentat/2019.1/Marc_tools/comp_damask_mp +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -usernoext=$user -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - -# add BLAS options for linking - BLAS="%BLAS%" - -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user on host `hostname`" -echo "program: $program" - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$usernoext.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $BLAS \ - $SYSLIBS || \ - { - echo "$0: link failed for $usernoext.o on host `hostname`" - exit 1 - } - /bin/rm $userobj - /bin/rm $DIRJOB/*.mod - /bin/rm $DIRJOB/*.smod diff --git a/installation/mods_MarcMentat/2019.1/Marc_tools/comp_user.original b/installation/mods_MarcMentat/2019.1/Marc_tools/comp_user.original deleted file mode 100644 index 8679bb041..000000000 --- a/installation/mods_MarcMentat/2019.1/Marc_tools/comp_user.original +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user.f on host `hostname`" -echo "program: $program" - $FORTRAN $user.f || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$user.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $SYSLIBS || \ - { - echo "$0: link failed for $user.o on host `hostname`" - exit 1 - } - /bin/rm $userobj diff --git a/installation/mods_MarcMentat/2019.1/Marc_tools/include_linux64 b/installation/mods_MarcMentat/2019.1/Marc_tools/include_linux64 deleted file mode 100644 index e0178a9c8..000000000 --- a/installation/mods_MarcMentat/2019.1/Marc_tools/include_linux64 +++ /dev/null @@ -1,818 +0,0 @@ -# -# General definitions for the Marc 2019 FP1 version -# -# EM64T -# -# Linux RedHat 7.1, 7.3 / SuSE 11 SP4, 12 SP1 -# -# 64 bit MPI version -# -# Intel(R) Fortran Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.5.239 Build 20170817 -# -# Intel(R) C Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.5.239 Build 20170817 -# -# To check the O/S level, type: -# uname -a -# -# Distributed parallel MPI libraries: -# 1) HP MPI 2.3 -# To check the mpi version, type: -# mpirun -version -# 2) Intel MPI 2017.1 -# To check the mpi version, type: -# mpiexec.hydra -version -# -# To check the Compiler level, type using the compiler -# installation path: -# ifort -V -# icc -V -# -# REMARKS : This file contains the definitions of variables used during -# compilation loading and use of the MARC programmes . The -# current machine type is identified by means of the variable -# MACHINE , defined below. -# -# -# MPI_ROOT: root directory in which mpi shared libraries, etc. are located -# DIRJOB : directory in which spawned jobs should look for Marc input -# MPI_ARCH: system architecture -# MPI_EPATH: path where executable resides -# -REVISION="VERSION, BUILD" -HOSTNAME=`hostname` - -# find available memory in Mbyte on the machine -# can be set explicitly -MEMLIMIT=`free -m | awk '/Mem:/ {print $2}'` - -# set _OEM_NASTRAN to 1 for MD Nastran build -# override _OEM_NASTRAN setting with MARC_MD_NASTRAN environment variable -_OEM_NASTRAN="${MARC_MD_NASTRAN:-0}" - -# uncomment the following line for an autoforge build -#AUTOFORGE=1 -AUTOFORGE=0 -export AUTOFORGE - -# integer size -if test "$MARC_INTEGER_SIZE" = "" ; then - INTEGER_PATH= -else - INTEGER_PATH=/$MARC_INTEGER_SIZE -fi - -FCOMP=ifort -INTELPATH="/opt/intel/compilers_and_libraries_2017/linux" - -# find the root directory of the compiler installation: -# - if ifort is found in $PATH, then the root directory is derived -# from the path to ifort -# - if ifort is not found in $PATH, the root directory is assumed -# to be $INTELPATH and the directory in which ifort is found is -# added to $PATH -FCOMPPATH=`which "$FCOMP" 2>/dev/null` -if test -n "$FCOMPPATH"; then - # derive the root directory from $FCOMPPATH - FCOMPROOT="${FCOMPPATH%/bin/intel64/$FCOMP}" - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT="${FCOMPPATH%/bin/$FCOMP}" - fi - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT= - fi -elif test -d "$INTELPATH"; then - # check for compiler in $INTELPATH - if test -d "$INTELPATH/bin/intel64" -a \ - -x "$INTELPATH/bin/intel64/$FCOMP" ; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin/intel64:$PATH" - elif test -d "$INTELPATH/bin" -a \ - -x "$INTELPATH/bin/$FCOMP"; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin:$PATH" - else - FCOMPROOT= - fi -else - FCOMPROOT= -fi - -# DAMASK uses the HDF5 compiler wrapper around the Intel compiler -H5FC="$(h5fc -shlib -show)" -HDF5_LIB=${H5FC//ifort/} -FCOMP="$H5FC -DDAMASK_HDF5" - -# AEM -if test "$MARCDLLOUTDIR" = ""; then - DLLOUTDIR="$MARC_LIB" -else - DLLOUTDIR="$MARCDLLOUTDIR" -fi - -# settings for MKL -if test "$IMKLDIR" = ""; then - MARC_MKL="$FCOMPROOT/mkl/lib/intel64" -else - MARC_MKL=$IMKLDIR/lib/intel64 -fi - -# -# settings for Metis -# -METIS="-I$METIS_SOURCE/include" -METISLIBS="$METISLIB_DIR/libmarcddm.a $METISLIB_DIR/libmarcmetis.a " - -# -# settings for MPI -# -# RCP and RSH are used for parallel network runs -# replace with similar commands like rsh if needed -RCP=/usr/bin/scp -RSH=/usr/bin/ssh -# - - -MPI_DEFAULT=intelmpi -MPI_OTHER=hpmpi - -MPITYPE=$MPI_DEFAULT - -if test $AUTOFORGE -then - if test $AUTOFORGE = 1 - then - MPITYPE=none - fi -fi - - -# overrule MPITYPE setting with environmental variable MARC_MPITYPE -if test $MARC_MPITYPE -then - MPITYPE=$MARC_MPITYPE -fi - -# always set MPITYPE to none for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - MPITYPE=none -fi - -# Edit following lines to build with GPGPU version of BCS Solver for -# NVIDIA platforms -#BCSGPUSOLVER=NONE -BCSGPUSOLVER=BCSGPU - -# Edit following lines to set the openssl library -if test "$OPENSSL" != "NONE" -then - OPENSSL_LIB="$MARC_LIB/libcrypto.a" -fi -OPENSSL_INCLUDE=-I"$MARC_OPENSSL/include/" - -MARCHDF_HDF=HDF -#MARCHDF_HDF=NONE -if test "$MARCHDF_HDF" = "HDF"; then - HDF_INCLUDE="-I$MARC_HDF/include" - HDF_LIBS="$MARC_LIB/libhdf5_fortran.so.100 $MARC_LIB/libhdf5.so.101" -fi - -# activate contact component build if flagged -AEM_DLL=0 -if test "$AEM_BUILD" = "ON" ; then - AEM_DLL=1 - LINK_MARC_DLL="-shared -fPIC" - EXT_DLL="so" - MPITYPE=none - MPI_OTHER= - BCSGPUSOLVER=NONE - MUMPSSOLVER=NONE - CASISOLVER=NONE -fi - -SOLVERFLAGS= -if test "$BCSGPUSOLVER" = BCSGPU -then - SOLVERFLAGS="$SOLVERFLAGS -DBCSGPU -DCUDA" - BCS_DIR=bcsgpusolver -else - BCS_DIR=bcssolver -fi -# -# settings for MPI -# -DDM= -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - FCOMPMPI=mpif90 - export MPI_ROOT=$MARC_HPMPI - export MPI_REMSH=$RSH - export MPI_F77=$FCOMP - ARCHITECTURE=linux_amd64 - DDM="-I$MPI_ROOT/include/64 -DDDM -DHPMPI" - MPI_CLEAN= - export MPI_EPATH=$MARC_BIN - export LD_LIBRARY_PATH=$MPI_ROOT/lib/$ARCHITECTURE:$MARC_LIB:$MARC_LIB_SHARED:$LD_LIBRARY_PATH - export MPIHPSPECIAL="-e MPI_FLAGS=E,T,y1" -# Below line is moved in run_marc file -# export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - export MPIHPSPECIAL="$MPIHPSPECIAL -e BINDIR=$MARC_BIN" - if test -n "$MSC_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e MSC_LICENSE_FILE=$MSC_LICENSE_FILE" - fi - if test -n "$LM_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LM_LICENSE_FILE=$LM_LICENSE_FILE" - fi - export MPIHPSPECIAL="$MPIHPSPECIAL -e MPI_LIC_CHECKER=$MPI_ROOT/bin/licensing/amd64_s8/lichk.x" - RUN_JOB2="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -f " - RUN_JOB1="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -w $MPIHPSPECIAL -np " - RUN_JOB0= - fi - if test $MPITYPE = intelmpi - then - INTELMPI_VERSION=HYDRA - FCOMPMPI=mpiifort - MPI_ROOT=$MARC_INTELMPI - DDM="-I${MPI_ROOT}/include -DDDM" - PATH=$MPI_ROOT/bin:$PATH - export PATH - LD_LIBRARY_PATH=$MPI_ROOT/lib:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - if test $INTELMPI_VERSION = HYDRA - then - RUN_JOB1="${MPI_ROOT}/bin/mpiexec.hydra -genvall -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec.hydra -genvall" - else - RUN_JOB1="${MPI_ROOT}/bin/mpiexec -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec -configfile " - fi - RUN_JOB0= - MPI_CLEAN= - MPI_EPATH=$MARC_BIN - MPIR_HOME=$MPI_ROOT - MPICH_F77=$FCOMP - MPICH_F77LINKER=$FCOMP - export MPI_ROOT MPI_EPATH MPIR_HOME MPICH_F77 MPICH_F77LINKER - I_MPI_PIN_DOMAIN=node - export I_MPI_PIN_DOMAIN - fi -else - MPI_ROOT=$MARC_DUMMYMPI - export MPI_ROOT=$MARC_DUMMYMPI - DDM="-I$MPI_ROOT/include" -fi - -# -# variables for the "maintain" script -# - -MACHINENAME=LINUX -MACHINE64BIT=yes -MACHINE=Linux_EM64T -DEV=/dev/tape -GETLOG="whoami" -CLEAR="clear" -MY_UNAME=`uname -a` - -# Edit following 2 lines to build with VKI Solver -#VKISOLVER=VKI -VKISOLVER=NONE - -# Edit following 2 lines to build with CASI Solver -CASISOLVER=CASI -if test "$MARC_CASISOLVER" = "NONE" ; then - CASISOLVER=NONE -fi -#CASISOLVER=NONE - -# Edit following 2 lines to build with MF2 Solver -MF2SOLVER=NONE -#MF2SOLVER=SERIAL -#MF2SOLVER=MF2PARALLEL - -# Edit following lines to build with Intel(c) Multithreaded solver (PARDISO) -#INTELSOLVER=NONE -INTELSOLVER=PARDISO - -# Edit following lines to build with MUMPS -if test "$MARC_INTEGER_SIZE" = "i4" ; then - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -else - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -fi - -# Edit following 2 lines to build MARC dynamic shared library -MARC_DLL=MARC_DLL -MARC_DLL=NONE - -# always set VKISOLVER, CASISOLVER, BCSGPUSOLVER, and MARC_DLL to NONE for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE - MARC_DLL=NONE -fi -if test "$AEM_DLL" -eq 1 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE -fi - -# -# define Fortran and C compile syntax -# -if test "$VKISOLVER" = VKI -then - SOLVERFLAGS="$SOLVERFLAGS -DVKI" -fi - -if test "$CASISOLVER" = CASI -then - SOLVERFLAGS="$SOLVERFLAGS -DCASI" -fi - -if test "$MF2SOLVER" = MF2PARALLEL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2PARALLEL" -fi -if test "$MF2SOLVER" = MF2SERIAL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2SERIAL" -fi - -if test "$INTELSOLVER" = PARDISO -then - SOLVERFLAGS="$SOLVERFLAGS -DPARDISO" -fi - -if test "$MUMPSSOLVER" = MUMPS -then - SOLVERFLAGS="$SOLVERFLAGS -DMUMPS" -fi - - -if test "$MARC_DLL" = MARC_DLL -then - SOLVERFLAGS="$SOLVERFLAGS -DMARC_DLL" -fi - -LINK_OPT= -DEBUG_OPT= -C_DEBUG_OPT= - -#Uncomment following line to build Marc in debuggable mode -MARCDEBUG= -#MARCDEBUG="ON" - -if test "$MARCDEBUG" = "ON" -then - LINK_OPT="-debug -traceback" - DEBUG_OPT="-debug -traceback" - C_DEBUG_OPT="-debug -traceback" -fi - - -MARCCHECK= -#MARCCHECK="ON" -if test "$MARCCHECK" = "ON" -then - DEBUG_OPT="$DEBUG_OPT -fpe0 -fp-stack-check -check all -ftrapuv " - C_DEBUG_OPT="$C_DEBUG_OPT -fp-stack-check -check-uninit -Wformat -ftrapuv " -fi - -MARCCODECOV= -#MARCCODECOV="ON" - -MARCCODEPROF= -#MARCCODEPROF="ON" - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - I8FFLAGS= - I8DEFINES= - I8CDEFINES= -else - I8FFLAGS="-i8 -integer-size 64" - I8DEFINES="-DI64 -DINT=8" - I8CDEFINES="-U_DOUBLE -D_SINGLE" -fi - -MTHREAD=OPENMP -if test "$MARC_OPENMP" = "NONE" ; then - MTHREAD=NONE -fi -#MTHREAD=NONE -if test "$_OEM_NASTRAN" -ne 0 -then -MTHREAD=NONE -fi -if test "$AEM_DLL" -eq 1 -then - MTHREAD=NONE - CASISOLVER=NONE - VKISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - BCSGPUSOLVER=NONE - OPENSSL_LIB= - MARC_DLL=NONE - METISLIBS= -fi - -OMP_COMPAT=NO -OMP_COMPAT=YES -if test "$MTHREAD" = "NONE" -then -OMP_COMPAT=NO -fi - -CDEFINES= -FDEFINES= - -if test "$_OEM_NASTRAN" -ne 0 -then - CDEFINES="$CDEFINES -D_OEM_NASTRAN" - FDEFINES="$FDEFINES -D_OEM_NASTRAN" -fi - -FDEFINES="$FDEFINES -D_IMPLICITNONE" - -if test "$_OEM_NASTRAN" -eq 0 -then - FDEFINES="$FDEFINES -DMKL -DOPENMP" -fi - -if test "$OMP_COMPAT" = "YES" -then - FDEFINES="$FDEFINES -DOMP_COMPAT" -fi - -# -D_MSCMARC -FDEFINES="$FDEFINES -D_MSCMARC $DEBUG_OPT $MARC_SIMUFACT" -CDEFINES="$CDEFINES -D_MSCMARC $C_DEBUG_OPT $I8CDEFINES" - -if test "$AEM_DLL" -eq 1 -then - FDEFINES="$FDEFINES -D_AEMNL -DAAA" - CDEFINES="$CDEFINES -D_AEMNL -DAAA" -fi - -CINCL="-I$MARC_SOURCE/mdsrc -I$MARC_SOURCE/csource $METIS -I$LAPI_IMPORTS/common/include" -if test "$_OEM_NASTRAN" -ne 0 -then - CINCL="$CINCL -I../../include" -fi - -CC_OPT= -if test "$MTHREAD" = "OPENMP" -then - CC_OPT=" $CC_OPT -qopenmp" -fi - -CC="icc -c $CC_OPT -O1 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCLOW="icc -c $CC_OPT -O0 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCHIGH="icc -c $CC_OPT -O3 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - -if test "$MARCDEBUG" = "ON" -then - CC="icc -c $CC_OPT -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCLOW="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCHIGH="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -fi - -LOAD_CC="icc $CC_OPT -O1 -DLinux -DLINUX -DLinux_intel" -CCT="$CC" -CCTLOW="$CCLOW" -CCTHIGH="$CCHIGH" - -#PROFILE="-Mprof=func" -#PROFILE="-Mprof=lines" -#PROFILE="-Mprof=func,mpi" -PROFILE= -#PROFILE="-init=snan,arrays -CB -traceback -fpe0 -fp-stack-check -check all -check uninit -ftrapuv" -if test "$MARCCODECOV" = "ON" -then -PROFILE="-prof-gen=srcpos" -fi -if test "$MARCCODEPROF" = "ON" -then -PROFILE=" $PROFILE -pg" -fi - -FORT_OPT="-c -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr -mp1 -WB -fp-model source" -if test "$MTHREAD" = "OPENMP" -then - FORT_OPT=" $FORT_OPT -qopenmp" - if test "$OMP_COMPAT" = "YES" - then - FORT_OPT=" $FORT_OPT -qopenmp-threadprivate=compat" - fi -else -# FORT_OPT=" $FORT_OPT -auto " - FORT_OPT=" $FORT_OPT -save -zero" -fi -if test "$MARCHDF_HDF" = "HDF"; then - FORT_OPT="$FORT_OPT -DMARCHDF=$MARCHDF_HDF" -fi - -FORTLOW="$FCOMP $FORT_OPT $PROFILE -O0 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTRAN="$FCOMP $FORT_OPT $PROFILE -O1 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTNA="$FCOMP $FORT_OPT -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -# for compiling free form f90 files. high opt, integer(4) -FORTF90="$FCOMP -c -O3" - -# determine DAMASK version -if test -n "$DAMASK_USER"; then - DAMASKROOT=`dirname $DAMASK_USER`/.. - read DAMASKVERSION < $DAMASKROOT/VERSION - DAMASKVERSION="'"$DAMASKVERSION"'" -else - DAMASKVERSION="'N/A'" -fi - - -# DAMASK compiler calls: additional flags are in line 2 OpenMP flags in line 3 -DFORTLOWMP="$FCOMP -c -O0 -qno-offload -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2019 -DDAMASKVERSION=$DAMASKVERSION \ - -qopenmp -qopenmp-threadprivate=compat\ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -DFORTRANMP="$FCOMP -c -O1 -qno-offload -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2019 -DDAMASKVERSION=$DAMASKVERSION \ - -qopenmp -qopenmp-threadprivate=compat\ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -DFORTHIGHMP="$FCOMP -c -O3 -qno-offload -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2019 -DDAMASKVERSION=$DAMASKVERSION \ - -qopenmp -qopenmp-threadprivate=compat\ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - -if test "$MARCDEBUG" = "ON" -then - FORTLOW="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTRAN="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTNA="$FCOMP $FORT_OPT -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -fi - - -FORTLOWT="$FORTLOW" -FORTRANT="$FORTRAN" -FORTHIGHT="$FORTHIGH" - -FORTRANMNF="$FCOMP -c $FDEFINES " -CCMNF="icc -c -O1 -DLinux -DLINUX -DLinux_intel -Dport2egcs -I$MARC_SOURCE/marctoadams/mnf/include -D_LARGEFILE64_SOURCE" - -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - LOAD="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - LOADT="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - fi -# Uncomment the following lines to turn on the tracer and commnet out the next 5 lines -# if test $MPITYPE = intelmpi -# then -# INCLUDEMPI="-I$MPI_ROOT/include -I$VT_ROOT/include" -# LOAD="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# LOADT="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# fi - if test $MPITYPE = intelmpi - then - LOAD="ifort $PROFILE $LINK_OPT -o " - LOADT="ifort $PROFILE $LINK_OPT -o " - fi -else - LOAD="$FCOMP $LINK_OPT -o " - LOADT="$FCOMP $LINK_OPT -o " -fi - -if test "$MARC_DLL" = MARC_DLL -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide -lpthread" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - -if test "$AEM_DLL" -eq 1 -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - - -XLIBS="-L/usr/X11/lib -lX11 " - -# -# define archive and ranlib syntax -# - -ARC="ar rvl" -ARD="ar dvl" -ARX="ar xl" -RAN="" - -# -# choose which libraries you want to use ( e.g. blas ) -# - -if test "$VKISOLVER" = VKI -then - VKISOLVERLIBS="$MARC_LIB/vkisolver.a" -else - VKISOLVERLIBS= -fi - -if test "$CASISOLVER" = CASI -then - CASISOLVERLIBS="$CASILIB_DIR/libmarccasi.a $CASILIB_DIR/libcasi.a" -else - CASISOLVERLIBS= -fi - -MF2SOLVERLIBS= -if test "$MF2SOLVER" = MF2PARALLEL -then - MF2SOLVERLIBS="$MARC_LIB/mf2parallel/libseq.a \ - $MARC_LIB/mf2parallel/libsym.a \ - $MARC_LIB/mf2parallel/libmet.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libnum.a \ - $MARC_LIB/mf2parallel/libutl.a \ - $MARC_LIB/mf2parallel/libr8.a \ - $MARC_LIB/mf2parallel/libz.a " -fi - -if test "$MUMPSSOLVER" = MUMPS -then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - if test $MPITYPE = none - then - MUMPSSOLVERLIBS2= - echo hello > /dev/null - fi - if test $MPITYPE = intelmpi - then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_intelmpi.a" - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a " - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a " - fi - fi - if test $MPITYPE = hpmpi - then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_hpmpi.a" - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a" - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a" - fi - fi -else - MUMPSSOLVERLIBS= - MUMPSSOLVERLIBS2= -fi - -if test "$BCSGPUSOLVER" = BCSGPU -then - BCSSOLVERLIBS="${BCSLIB_DIR}/bcsgpulib.a " - MARCCUDALIBS1="-L${BCSLIB_DIR}/cuda_dummy -lmarccuda " - MARCCUDALIBS2="-L${BCSLIB_DIR}/cuda -lmarccuda " - MARCCUDALIBS=$MARCCUDALIBS1 -else - BCSSOLVERLIBS="${MARC_LIB}/bcslib.a " -fi -if test "$AEM_DLL" -eq 1 -then - BCSSOLVERLIBS= -fi - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - MKLLIB="$MARC_MKL/libmkl_scalapack_lp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_lp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MARC_MKL/libmkl_blacs_intelmpi_lp64.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -else - MKLLIB="$MARC_MKL/libmkl_scalapack_ilp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_ilp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -fi - -SECLIBS="-L$MARC_LIB -llapi" - -SOLVERLIBS="${BCSSOLVERLIBS} ${VKISOLVERLIBS} ${CASISOLVERLIBS} ${MF2SOLVERLIBS} \ - $MKLLIB -L$MARC_MKL -liomp5 \ - $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/kdtree2.a $HDF5_LIB" - -SOLVERLIBS_DLL=${SOLVERLIBS} -if test "$AEM_DLL" -eq 1 -then -SOLVERLIBS_DLL="$MKLLIB -L$MARC_MKL -liomp5 $MARC_LIB/blas_src.a" -fi -MRCLIBS="$MARC_LIB/clib.a ${CASISOLVERLIBS}" -MRCLIBSPAR="$MARC_LIB/clib.a" -STUBS="$MARC_LIB/stubs.a " -MNFLIBS="$MARC_LIB/libmnf.a" -MDUSER="$MARC_LIB/md_user.a" -if test "X$MARC_SIMUFACT" != "X" -then - SFLIB="-L$SFMATDIR -lMBA_Grain" -else - SFLIB=" " -fi -OPENMP="-qopenmp" - -if test "$AEM_DLL" -eq 1 -then - LOAD_DLL=$LOAD - OPENMP= - LIBMNF= - OPENSSL=NONE -fi - -SYSLIBS=" $OPENMP -lpthread -cxxlib" - -# Uncomment the following lines to turn on the trace and comment out the next 4 lines -# if test $MPITYPE = intelmpi -# then -# SYSLIBS="-L${VT_ROOT}/lib -lVT -ldwarf -lelf -lm -lpthread \ -# -L${MPI_ROOT}/lib64 -lmpi -lmpiif -lmpigi -lrt" -# fi -if test $MPITYPE = intelmpi -then - SYSLIBS="-L${MPI_ROOT}/lib -lmpi_mt -lmpifort -lrt $OPENMP -threads -lpthread -cxxlib" -fi - - -SYSLIBSPAR=" " - -MARC_DLL_CODES="runmarc.f" - - -BLAS_SRC="dzero.f icopy.f izero.f" -if test "$_OEM_NASTRAN" -ne 0 -then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - BLAS_SRC="$BLAS_SRC dsctr.f zsctr.f dzasum.f daxpyi.f zaxpyi.f dgthr.f zgthr.f" - else - BLAS_SRC="ALL" - fi -fi - -LOW_OPT_CODES="are163.f contro.f ndext.f omarc.f omarca.f omarcb.f omarcc.f \ - omars.f fixbc.f triang.f bet049.f norst3.f eldata.f \ - elec*.f elct*.f fmeig.f oada00.f ogeig.f updtrbe2.f cycrota.f \ - cordef.f ogpk.f ogtan.f eldam.f formrbe3.f \ - inertie.f em_sso072.f cn_fol3d_qpatch6.f cosim_begin.f" -if test "$MARC_INTEGER_SIZE" = "i8" ; then - LOW_OPT_CODES="$LOW_OPT_CODES bbcseg.f" -fi - -HIGH_OPT_CODES="dpsmsa1.f dpsmsa2.f dpsmsa3.f dpsmsa4.f dpsmsa5.f dpsmsa6.f \ - dpsmsa7.f dpsmsa8.f dpsmsa9.f dpsmsa10.f dpsmsa11.f dpsmsa12.f \ - dpsmsa13.f dpsmsa14.f dpsmsa15.f dpsmsa16.f dpsmsah.f tpsmsah.f cn_qsort4_11.f \ - prei11.f prei12.f prei31.f prei32.f prei41.f prei42.f prei61.f prei62.f \ - prei1n.f prei2n.f cgfullnts1.f cgfullnts2.f cg1n.f cg2n.f cg3n.f \ - cg4n.f cg5n.f cg6n.f cgnn.f sortab.f sortab1.f triann1.f preinv_nts.f " - - - -MAXNUM=1000000 diff --git a/installation/mods_MarcMentat/2019.1/Marc_tools/include_linux64.original b/installation/mods_MarcMentat/2019.1/Marc_tools/include_linux64.original deleted file mode 100644 index 224d3b6d6..000000000 --- a/installation/mods_MarcMentat/2019.1/Marc_tools/include_linux64.original +++ /dev/null @@ -1,788 +0,0 @@ -# -# General definitions for the Marc 2019 FP1 version -# -# EM64T -# -# Linux RedHat 7.1, 7.3 / SuSE 11 SP4, 12 SP1 -# -# 64 bit MPI version -# -# Intel(R) Fortran Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.5.239 Build 20170817 -# -# Intel(R) C Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.5.239 Build 20170817 -# -# To check the O/S level, type: -# uname -a -# -# Distributed parallel MPI libraries: -# 1) HP MPI 2.3 -# To check the mpi version, type: -# mpirun -version -# 2) Intel MPI 2017.1 -# To check the mpi version, type: -# mpiexec.hydra -version -# -# To check the Compiler level, type using the compiler -# installation path: -# ifort -V -# icc -V -# -# REMARKS : This file contains the definitions of variables used during -# compilation loading and use of the MARC programmes . The -# current machine type is identified by means of the variable -# MACHINE , defined below. -# -# -# MPI_ROOT: root directory in which mpi shared libraries, etc. are located -# DIRJOB : directory in which spawned jobs should look for Marc input -# MPI_ARCH: system architecture -# MPI_EPATH: path where executable resides -# -REVISION="VERSION, BUILD" -HOSTNAME=`hostname` - -# find available memory in Mbyte on the machine -# can be set explicitly -MEMLIMIT=`free -m | awk '/Mem:/ {print $2}'` - -# set _OEM_NASTRAN to 1 for MD Nastran build -# override _OEM_NASTRAN setting with MARC_MD_NASTRAN environment variable -_OEM_NASTRAN="${MARC_MD_NASTRAN:-0}" - -# uncomment the following line for an autoforge build -#AUTOFORGE=1 -AUTOFORGE=0 -export AUTOFORGE - -# integer size -if test "$MARC_INTEGER_SIZE" = "" ; then - INTEGER_PATH= -else - INTEGER_PATH=/$MARC_INTEGER_SIZE -fi - -FCOMP=ifort -INTELPATH="/opt/intel/compilers_and_libraries_2017/linux" - -# find the root directory of the compiler installation: -# - if ifort is found in $PATH, then the root directory is derived -# from the path to ifort -# - if ifort is not found in $PATH, the root directory is assumed -# to be $INTELPATH and the directory in which ifort is found is -# added to $PATH -FCOMPPATH=`which "$FCOMP" 2>/dev/null` -if test -n "$FCOMPPATH"; then - # derive the root directory from $FCOMPPATH - FCOMPROOT="${FCOMPPATH%/bin/intel64/$FCOMP}" - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT="${FCOMPPATH%/bin/$FCOMP}" - fi - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT= - fi -elif test -d "$INTELPATH"; then - # check for compiler in $INTELPATH - if test -d "$INTELPATH/bin/intel64" -a \ - -x "$INTELPATH/bin/intel64/$FCOMP" ; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin/intel64:$PATH" - elif test -d "$INTELPATH/bin" -a \ - -x "$INTELPATH/bin/$FCOMP"; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin:$PATH" - else - FCOMPROOT= - fi -else - FCOMPROOT= -fi - -# AEM -if test "$MARCDLLOUTDIR" = ""; then - DLLOUTDIR="$MARC_LIB" -else - DLLOUTDIR="$MARCDLLOUTDIR" -fi - -# settings for MKL -if test "$IMKLDIR" = ""; then - MARC_MKL="$FCOMPROOT/mkl/lib/intel64" -else - MARC_MKL=$IMKLDIR/lib/intel64 -fi - -# -# settings for Metis -# -METIS="-I$METIS_SOURCE/include" -METISLIBS="$METISLIB_DIR/libmarcddm.a $METISLIB_DIR/libmarcmetis.a " - -# -# settings for MPI -# -# RCP and RSH are used for parallel network runs -# replace with similar commands like rsh if needed -RCP=/usr/bin/scp -RSH=/usr/bin/ssh -# - - -MPI_DEFAULT=intelmpi -MPI_OTHER=hpmpi - -MPITYPE=$MPI_DEFAULT - -if test $AUTOFORGE -then - if test $AUTOFORGE = 1 - then - MPITYPE=none - fi -fi - - -# overrule MPITYPE setting with environmental variable MARC_MPITYPE -if test $MARC_MPITYPE -then - MPITYPE=$MARC_MPITYPE -fi - -# always set MPITYPE to none for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - MPITYPE=none -fi - -# Edit following lines to build with GPGPU version of BCS Solver for -# NVIDIA platforms -#BCSGPUSOLVER=NONE -BCSGPUSOLVER=BCSGPU - -# Edit following lines to set the openssl library -if test "$OPENSSL" != "NONE" -then - OPENSSL_LIB="$MARC_LIB/libcrypto.a" -fi -OPENSSL_INCLUDE=-I"$MARC_OPENSSL/include/" - -MARCHDF_HDF=HDF -#MARCHDF_HDF=NONE -if test "$MARCHDF_HDF" = "HDF"; then - HDF_INCLUDE="-I$MARC_HDF/include" - HDF_LIBS="$MARC_LIB/libhdf5_fortran.so.100 $MARC_LIB/libhdf5.so.101" -fi - -# activate contact component build if flagged -AEM_DLL=0 -if test "$AEM_BUILD" = "ON" ; then - AEM_DLL=1 - LINK_MARC_DLL="-shared -fPIC" - EXT_DLL="so" - MPITYPE=none - MPI_OTHER= - BCSGPUSOLVER=NONE - MUMPSSOLVER=NONE - CASISOLVER=NONE -fi - -SOLVERFLAGS= -if test "$BCSGPUSOLVER" = BCSGPU -then - SOLVERFLAGS="$SOLVERFLAGS -DBCSGPU -DCUDA" - BCS_DIR=bcsgpusolver -else - BCS_DIR=bcssolver -fi -# -# settings for MPI -# -DDM= -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - FCOMPMPI=mpif90 - export MPI_ROOT=$MARC_HPMPI - export MPI_REMSH=$RSH - export MPI_F77=$FCOMP - ARCHITECTURE=linux_amd64 - DDM="-I$MPI_ROOT/include/64 -DDDM -DHPMPI" - MPI_CLEAN= - export MPI_EPATH=$MARC_BIN - export LD_LIBRARY_PATH=$MPI_ROOT/lib/$ARCHITECTURE:$MARC_LIB:$MARC_LIB_SHARED:$LD_LIBRARY_PATH - export MPIHPSPECIAL="-e MPI_FLAGS=E,T,y1" -# Below line is moved in run_marc file -# export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - export MPIHPSPECIAL="$MPIHPSPECIAL -e BINDIR=$MARC_BIN" - if test -n "$MSC_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e MSC_LICENSE_FILE=$MSC_LICENSE_FILE" - fi - if test -n "$LM_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LM_LICENSE_FILE=$LM_LICENSE_FILE" - fi - export MPIHPSPECIAL="$MPIHPSPECIAL -e MPI_LIC_CHECKER=$MPI_ROOT/bin/licensing/amd64_s8/lichk.x" - RUN_JOB2="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -f " - RUN_JOB1="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -w $MPIHPSPECIAL -np " - RUN_JOB0= - fi - if test $MPITYPE = intelmpi - then - INTELMPI_VERSION=HYDRA - FCOMPMPI=mpiifort - MPI_ROOT=$MARC_INTELMPI - DDM="-I${MPI_ROOT}/include -DDDM" - PATH=$MPI_ROOT/bin:$PATH - export PATH - LD_LIBRARY_PATH=$MPI_ROOT/lib:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - if test $INTELMPI_VERSION = HYDRA - then - RUN_JOB1="${MPI_ROOT}/bin/mpiexec.hydra -genvall -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec.hydra -genvall" - else - RUN_JOB1="${MPI_ROOT}/bin/mpiexec -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec -configfile " - fi - RUN_JOB0= - MPI_CLEAN= - MPI_EPATH=$MARC_BIN - MPIR_HOME=$MPI_ROOT - MPICH_F77=$FCOMP - MPICH_F77LINKER=$FCOMP - export MPI_ROOT MPI_EPATH MPIR_HOME MPICH_F77 MPICH_F77LINKER - I_MPI_PIN_DOMAIN=node - export I_MPI_PIN_DOMAIN - fi -else - MPI_ROOT=$MARC_DUMMYMPI - export MPI_ROOT=$MARC_DUMMYMPI - DDM="-I$MPI_ROOT/include" -fi - -# -# variables for the "maintain" script -# - -MACHINENAME=LINUX -MACHINE64BIT=yes -MACHINE=Linux_EM64T -DEV=/dev/tape -GETLOG="whoami" -CLEAR="clear" -MY_UNAME=`uname -a` - -# Edit following 2 lines to build with VKI Solver -#VKISOLVER=VKI -VKISOLVER=NONE - -# Edit following 2 lines to build with CASI Solver -CASISOLVER=CASI -if test "$MARC_CASISOLVER" = "NONE" ; then - CASISOLVER=NONE -fi -#CASISOLVER=NONE - -# Edit following 2 lines to build with MF2 Solver -MF2SOLVER=NONE -#MF2SOLVER=SERIAL -#MF2SOLVER=MF2PARALLEL - -# Edit following lines to build with Intel(c) Multithreaded solver (PARDISO) -#INTELSOLVER=NONE -INTELSOLVER=PARDISO - -# Edit following lines to build with MUMPS -if test "$MARC_INTEGER_SIZE" = "i4" ; then - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -else - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -fi - -# Edit following 2 lines to build MARC dynamic shared library -MARC_DLL=MARC_DLL -MARC_DLL=NONE - -# always set VKISOLVER, CASISOLVER, BCSGPUSOLVER, and MARC_DLL to NONE for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE - MARC_DLL=NONE -fi -if test "$AEM_DLL" -eq 1 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE -fi - -# -# define Fortran and C compile syntax -# -if test "$VKISOLVER" = VKI -then - SOLVERFLAGS="$SOLVERFLAGS -DVKI" -fi - -if test "$CASISOLVER" = CASI -then - SOLVERFLAGS="$SOLVERFLAGS -DCASI" -fi - -if test "$MF2SOLVER" = MF2PARALLEL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2PARALLEL" -fi -if test "$MF2SOLVER" = MF2SERIAL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2SERIAL" -fi - -if test "$INTELSOLVER" = PARDISO -then - SOLVERFLAGS="$SOLVERFLAGS -DPARDISO" -fi - -if test "$MUMPSSOLVER" = MUMPS -then - SOLVERFLAGS="$SOLVERFLAGS -DMUMPS" -fi - - -if test "$MARC_DLL" = MARC_DLL -then - SOLVERFLAGS="$SOLVERFLAGS -DMARC_DLL" -fi - -LINK_OPT= -DEBUG_OPT= -C_DEBUG_OPT= - -#Uncomment following line to build Marc in debuggable mode -MARCDEBUG= -#MARCDEBUG="ON" - -if test "$MARCDEBUG" = "ON" -then - LINK_OPT="-debug -traceback" - DEBUG_OPT="-debug -traceback" - C_DEBUG_OPT="-debug -traceback" -fi - - -MARCCHECK= -#MARCCHECK="ON" -if test "$MARCCHECK" = "ON" -then - DEBUG_OPT="$DEBUG_OPT -fpe0 -fp-stack-check -check all -ftrapuv " - C_DEBUG_OPT="$C_DEBUG_OPT -fp-stack-check -check-uninit -Wformat -ftrapuv " -fi - -MARCCODECOV= -#MARCCODECOV="ON" - -MARCCODEPROF= -#MARCCODEPROF="ON" - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - I8FFLAGS= - I8DEFINES= - I8CDEFINES= -else - I8FFLAGS="-i8" - I8DEFINES="-DI64" - I8CDEFINES="-U_DOUBLE -D_SINGLE" -fi - -MTHREAD=OPENMP -if test "$MARC_OPENMP" = "NONE" ; then - MTHREAD=NONE -fi -#MTHREAD=NONE -if test "$_OEM_NASTRAN" -ne 0 -then -MTHREAD=NONE -fi -if test "$AEM_DLL" -eq 1 -then - MTHREAD=NONE - CASISOLVER=NONE - VKISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - BCSGPUSOLVER=NONE - OPENSSL_LIB= - MARC_DLL=NONE - METISLIBS= -fi - -OMP_COMPAT=NO -OMP_COMPAT=YES -if test "$MTHREAD" = "NONE" -then -OMP_COMPAT=NO -fi - -CDEFINES= -FDEFINES= - -if test "$_OEM_NASTRAN" -ne 0 -then - CDEFINES="$CDEFINES -D_OEM_NASTRAN" - FDEFINES="$FDEFINES -D_OEM_NASTRAN" -fi - -FDEFINES="$FDEFINES -D_IMPLICITNONE" - -if test "$_OEM_NASTRAN" -eq 0 -then - FDEFINES="$FDEFINES -DMKL -DOPENMP" -fi - -if test "$OMP_COMPAT" = "YES" -then - FDEFINES="$FDEFINES -DOMP_COMPAT" -fi - -# -D_MSCMARC -FDEFINES="$FDEFINES -D_MSCMARC $DEBUG_OPT $MARC_SIMUFACT" -CDEFINES="$CDEFINES -D_MSCMARC $C_DEBUG_OPT $I8CDEFINES" - -if test "$AEM_DLL" -eq 1 -then - FDEFINES="$FDEFINES -D_AEMNL -DAAA" - CDEFINES="$CDEFINES -D_AEMNL -DAAA" -fi - -CINCL="-I$MARC_SOURCE/mdsrc -I$MARC_SOURCE/csource $METIS -I$LAPI_IMPORTS/common/include" -if test "$_OEM_NASTRAN" -ne 0 -then - CINCL="$CINCL -I../../include" -fi - -CC_OPT= -if test "$MTHREAD" = "OPENMP" -then - CC_OPT=" $CC_OPT -qopenmp" -fi - -CC="icc -c $CC_OPT -O1 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCLOW="icc -c $CC_OPT -O0 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCHIGH="icc -c $CC_OPT -O3 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - -if test "$MARCDEBUG" = "ON" -then - CC="icc -c $CC_OPT -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCLOW="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCHIGH="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -fi - -LOAD_CC="icc $CC_OPT -O1 -DLinux -DLINUX -DLinux_intel" -CCT="$CC" -CCTLOW="$CCLOW" -CCTHIGH="$CCHIGH" - -#PROFILE="-Mprof=func" -#PROFILE="-Mprof=lines" -#PROFILE="-Mprof=func,mpi" -PROFILE= -#PROFILE="-init=snan,arrays -CB -traceback -fpe0 -fp-stack-check -check all -check uninit -ftrapuv" -if test "$MARCCODECOV" = "ON" -then -PROFILE="-prof-gen=srcpos" -fi -if test "$MARCCODEPROF" = "ON" -then -PROFILE=" $PROFILE -pg" -fi - -FORT_OPT="-c -assume byterecl -safe_cray_ptr -mp1 -WB -fp-model source" -if test "$MTHREAD" = "OPENMP" -then - FORT_OPT=" $FORT_OPT -qopenmp" - if test "$OMP_COMPAT" = "YES" - then - FORT_OPT=" $FORT_OPT -qopenmp-threadprivate=compat" - fi -else -# FORT_OPT=" $FORT_OPT -auto " - FORT_OPT=" $FORT_OPT -save -zero" -fi -if test "$MARCHDF_HDF" = "HDF"; then - FORT_OPT="$FORT_OPT -DMARCHDF_HDF=$MARCHDF_HDF $HDF_INCLUDE" -fi - -FORTLOW="$FCOMP $FORT_OPT $PROFILE -O0 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTRAN="$FCOMP $FORT_OPT $PROFILE -O1 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTNA="$FCOMP $FORT_OPT -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -# for compiling free form f90 files. high opt, integer(4) -FORTF90="$FCOMP -c -O3" - -if test "$MARCDEBUG" = "ON" -then - FORTLOW="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTRAN="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTNA="$FCOMP $FORT_OPT -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -fi - -FORTLOWT="$FORTLOW" -FORTRANT="$FORTRAN" -FORTHIGHT="$FORTHIGH" - -FORTRANMNF="$FCOMP -c $FDEFINES " -CCMNF="icc -c -O1 -DLinux -DLINUX -DLinux_intel -Dport2egcs -I$MARC_SOURCE/marctoadams/mnf/include -D_LARGEFILE64_SOURCE" - -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - LOAD="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - LOADT="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - fi -# Uncomment the following lines to turn on the tracer and commnet out the next 5 lines -# if test $MPITYPE = intelmpi -# then -# INCLUDEMPI="-I$MPI_ROOT/include -I$VT_ROOT/include" -# LOAD="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# LOADT="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# fi - if test $MPITYPE = intelmpi - then - LOAD="ifort $PROFILE $LINK_OPT -o " - LOADT="ifort $PROFILE $LINK_OPT -o " - fi -else - LOAD="$FCOMP $LINK_OPT -o " - LOADT="$FCOMP $LINK_OPT -o " -fi - -if test "$MARC_DLL" = MARC_DLL -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide -lpthread" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - -if test "$AEM_DLL" -eq 1 -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - - -XLIBS="-L/usr/X11/lib -lX11 " - -# -# define archive and ranlib syntax -# - -ARC="ar rvl" -ARD="ar dvl" -ARX="ar xl" -RAN="" - -# -# choose which libraries you want to use ( e.g. blas ) -# - -if test "$VKISOLVER" = VKI -then - VKISOLVERLIBS="$MARC_LIB/vkisolver.a" -else - VKISOLVERLIBS= -fi - -if test "$CASISOLVER" = CASI -then - CASISOLVERLIBS="$CASILIB_DIR/libmarccasi.a $CASILIB_DIR/libcasi.a" -else - CASISOLVERLIBS= -fi - -MF2SOLVERLIBS= -if test "$MF2SOLVER" = MF2PARALLEL -then - MF2SOLVERLIBS="$MARC_LIB/mf2parallel/libseq.a \ - $MARC_LIB/mf2parallel/libsym.a \ - $MARC_LIB/mf2parallel/libmet.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libnum.a \ - $MARC_LIB/mf2parallel/libutl.a \ - $MARC_LIB/mf2parallel/libr8.a \ - $MARC_LIB/mf2parallel/libz.a " -fi - -if test "$MUMPSSOLVER" = MUMPS -then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - if test $MPITYPE = none - then - MUMPSSOLVERLIBS2= - echo hello > /dev/null - fi - if test $MPITYPE = intelmpi - then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_intelmpi.a" - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a " - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a " - fi - fi - if test $MPITYPE = hpmpi - then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_hpmpi.a" - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a" - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a" - fi - fi -else - MUMPSSOLVERLIBS= - MUMPSSOLVERLIBS2= -fi - -if test "$BCSGPUSOLVER" = BCSGPU -then - BCSSOLVERLIBS="${BCSLIB_DIR}/bcsgpulib.a " - MARCCUDALIBS1="-L${BCSLIB_DIR}/cuda_dummy -lmarccuda " - MARCCUDALIBS2="-L${BCSLIB_DIR}/cuda -lmarccuda " - MARCCUDALIBS=$MARCCUDALIBS1 -else - BCSSOLVERLIBS="${MARC_LIB}/bcslib.a " -fi -if test "$AEM_DLL" -eq 1 -then - BCSSOLVERLIBS= -fi - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - MKLLIB="$MARC_MKL/libmkl_scalapack_lp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_lp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -else - MKLLIB="$MARC_MKL/libmkl_scalapack_ilp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_ilp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -fi - -SECLIBS="-L$MARC_LIB -llapi" - -SOLVERLIBS="${BCSSOLVERLIBS} ${VKISOLVERLIBS} ${CASISOLVERLIBS} ${MF2SOLVERLIBS} \ - $MKLLIB -L$MARC_MKL -liomp5 \ - $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/kdtree2.a $HDF_LIBS" - -SOLVERLIBS_DLL=${SOLVERLIBS} -if test "$AEM_DLL" -eq 1 -then -SOLVERLIBS_DLL="$MKLLIB -L$MARC_MKL -liomp5 $MARC_LIB/blas_src.a" -fi -MRCLIBS="$MARC_LIB/clib.a ${CASISOLVERLIBS}" -MRCLIBSPAR="$MARC_LIB/clib.a" -STUBS="$MARC_LIB/stubs.a " -MNFLIBS="$MARC_LIB/libmnf.a" -MDUSER="$MARC_LIB/md_user.a" -if test "X$MARC_SIMUFACT" != "X" -then - SFLIB="-L$SFMATDIR -lMBA_Grain" -else - SFLIB=" " -fi -OPENMP="-qopenmp" - -if test "$AEM_DLL" -eq 1 -then - LOAD_DLL=$LOAD - OPENMP= - LIBMNF= - OPENSSL=NONE -fi - -SYSLIBS=" $OPENMP -lpthread -shared-intel -cxxlib" - -# Uncomment the following lines to turn on the trace and comment out the next 4 lines -# if test $MPITYPE = intelmpi -# then -# SYSLIBS="-L${VT_ROOT}/lib -lVT -ldwarf -lelf -lm -lpthread \ -# -L${MPI_ROOT}/lib64 -lmpi -lmpiif -lmpigi -lrt" -# fi -if test $MPITYPE = intelmpi -then - SYSLIBS="-L${MPI_ROOT}/lib -lmpi_mt -lmpifort -lrt $OPENMP -threads -lpthread -shared-intel -cxxlib" -fi - - -SYSLIBSPAR=" " - -MARC_DLL_CODES="runmarc.f" - - -BLAS_SRC="dzero.f icopy.f izero.f" -if test "$_OEM_NASTRAN" -ne 0 -then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - BLAS_SRC="$BLAS_SRC dsctr.f zsctr.f dzasum.f daxpyi.f zaxpyi.f dgthr.f zgthr.f" - else - BLAS_SRC="ALL" - fi -fi - -LOW_OPT_CODES="are163.f contro.f ndext.f omarc.f omarca.f omarcb.f omarcc.f \ - omars.f fixbc.f triang.f bet049.f norst3.f eldata.f \ - elec*.f elct*.f fmeig.f oada00.f ogeig.f updtrbe2.f cycrota.f \ - cordef.f ogpk.f ogtan.f eldam.f formrbe3.f \ - inertie.f em_sso072.f cn_fol3d_qpatch6.f cosim_begin.f" -if test "$MARC_INTEGER_SIZE" = "i8" ; then - LOW_OPT_CODES="$LOW_OPT_CODES bbcseg.f" -fi - -HIGH_OPT_CODES="dpsmsa1.f dpsmsa2.f dpsmsa3.f dpsmsa4.f dpsmsa5.f dpsmsa6.f \ - dpsmsa7.f dpsmsa8.f dpsmsa9.f dpsmsa10.f dpsmsa11.f dpsmsa12.f \ - dpsmsa13.f dpsmsa14.f dpsmsa15.f dpsmsa16.f dpsmsah.f tpsmsah.f cn_qsort4_11.f \ - prei11.f prei12.f prei31.f prei32.f prei41.f prei42.f prei61.f prei62.f \ - prei1n.f prei2n.f cgfullnts1.f cgfullnts2.f cg1n.f cg2n.f cg3n.f \ - cg4n.f cg5n.f cg6n.f cgnn.f sortab.f sortab1.f triann1.f preinv_nts.f " - - - -MAXNUM=1000000 diff --git a/installation/mods_MarcMentat/2019.1/Marc_tools/run_damask_hmp b/installation/mods_MarcMentat/2019.1/Marc_tools/run_damask_hmp deleted file mode 100644 index 93bb6fe92..000000000 --- a/installation/mods_MarcMentat/2019.1/Marc_tools/run_damask_hmp +++ /dev/null @@ -1,4108 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - - -# getting user subroutine file name -found=0 -for i in "$@"; do - if test $found = 1; then - DAMASK_USER=$i - found=0 - fi - case $i in - -u* | -U*) - found=1 - ;; - esac -done -# sourcing include_linux64 (needs DAMASK_USER to be set) -. $MARC_INCLUDE - -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH:$SFMATDIR -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\+\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usernoext= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto= -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -SRCLIB=$MARC_LIB/srclib.a -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - echo - echo warning: the option -au is no longer supported and will be ignored - echo - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_intelmpi.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi -if test "$iam" = sim ; then - SFLIB="-L$SFMATDIR -lMBA_Grain" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - if test ! -f $user - then - error="$error -user subroutine file $user not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" -fi -fi - -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($user)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# -# add DAMASK options for linking - DAMASK="-lstdc++" - - if test "$user" - then - program=$usernoext.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$usernoext.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -# -# check for external file to run using valgrind -# -if test -f $MARC_TOOLS/run_marc_valgrind -then - . $MARC_TOOLS/run_marc_valgrind -fi - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$usermoext.o - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test $MACHINENAME = "CRAY" - then - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTHIGHMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $SRCLIB \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $SFLIB \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTHIGHMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $SRCLIB \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $SFLIB \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$BINDIR/exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTHIGHMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $SRCLIB \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $SFLIB \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$BINDIR/exeddm $RUN_JOB -ddm $ddm_arc " -fi - - $RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2019.1/Marc_tools/run_damask_lmp b/installation/mods_MarcMentat/2019.1/Marc_tools/run_damask_lmp deleted file mode 100644 index 1d4dbd0c3..000000000 --- a/installation/mods_MarcMentat/2019.1/Marc_tools/run_damask_lmp +++ /dev/null @@ -1,4108 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - - -# getting user subroutine file name -found=0 -for i in "$@"; do - if test $found = 1; then - DAMASK_USER=$i - found=0 - fi - case $i in - -u* | -U*) - found=1 - ;; - esac -done -# sourcing include_linux64 (needs DAMASK_USER to be set) -. $MARC_INCLUDE - -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH:$SFMATDIR -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\+\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usernoext= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto= -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -SRCLIB=$MARC_LIB/srclib.a -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - echo - echo warning: the option -au is no longer supported and will be ignored - echo - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_intelmpi.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi -if test "$iam" = sim ; then - SFLIB="-L$SFMATDIR -lMBA_Grain" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - if test ! -f $user - then - error="$error -user subroutine file $user not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" -fi -fi - -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($user)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# -# add DAMASK options for linking - DAMASK="-lstdc++" - - if test "$user" - then - program=$usernoext.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$usernoext.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -# -# check for external file to run using valgrind -# -if test -f $MARC_TOOLS/run_marc_valgrind -then - . $MARC_TOOLS/run_marc_valgrind -fi - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$usermoext.o - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test $MACHINENAME = "CRAY" - then - $DFORTLOWMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTLOWMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $SRCLIB \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $SFLIB \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_lmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTLOWMP $user || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTLOWMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $SRCLIB \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $SFLIB \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$BINDIR/exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_lmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTLOWMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTLOWMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $SRCLIB \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $SFLIB \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$BINDIR/exeddm $RUN_JOB -ddm $ddm_arc " -fi - - $RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2019.1/Marc_tools/run_damask_mp b/installation/mods_MarcMentat/2019.1/Marc_tools/run_damask_mp deleted file mode 100644 index 36c393444..000000000 --- a/installation/mods_MarcMentat/2019.1/Marc_tools/run_damask_mp +++ /dev/null @@ -1,4108 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - - -# getting user subroutine file name -found=0 -for i in "$@"; do - if test $found = 1; then - DAMASK_USER=$i - found=0 - fi - case $i in - -u* | -U*) - found=1 - ;; - esac -done -# sourcing include_linux64 (needs DAMASK_USER to be set) -. $MARC_INCLUDE - -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH:$SFMATDIR -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\+\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usernoext= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto= -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -SRCLIB=$MARC_LIB/srclib.a -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - echo - echo warning: the option -au is no longer supported and will be ignored - echo - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_intelmpi.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi -if test "$iam" = sim ; then - SFLIB="-L$SFMATDIR -lMBA_Grain" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - if test ! -f $user - then - error="$error -user subroutine file $user not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" -fi -fi - -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($user)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# -# add DAMASK options for linking - DAMASK="-lstdc++" - - if test "$user" - then - program=$usernoext.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$usernoext.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -# -# check for external file to run using valgrind -# -if test -f $MARC_TOOLS/run_marc_valgrind -then - . $MARC_TOOLS/run_marc_valgrind -fi - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$usermoext.o - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test $MACHINENAME = "CRAY" - then - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTRANMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $SRCLIB \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $SFLIB \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTRANMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $SRCLIB \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $SFLIB \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$BINDIR/exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTRANMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $SRCLIB \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $SFLIB \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$BINDIR/exeddm $RUN_JOB -ddm $ddm_arc " -fi - - $RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2019.1/Marc_tools/run_marc.original b/installation/mods_MarcMentat/2019.1/Marc_tools/run_marc.original deleted file mode 100644 index c0bf00643..000000000 --- a/installation/mods_MarcMentat/2019.1/Marc_tools/run_marc.original +++ /dev/null @@ -1,4186 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - -. $MARC_INCLUDE -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH:$SFMATDIR -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\+\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usersubname= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto= -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -SRCLIB=$MARC_LIB/srclib.a -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user - basefile=`$BASENAME $value` - if test ${basefile##*.} = f - then - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user.f - elif test ${basefile##*.} = F - then - user=`dirname $value`/`$BASENAME $value .F` - usersubname=$user.F - elif test ${basefile##*.} = f90 - then - user=`dirname $value`/`$BASENAME $value .f90` - usersubname=$user.f90 - elif test ${basefile##*.} = F90 - then - user=`dirname $value`/`$BASENAME $value .F90` - usersubname=$user.F90 - fi - case $user in - \/*) - ;; - *) - user=`pwd`/$user - usersubname=`pwd`/$usersubname - ;; - esac - if test ! -f $usersubname - then - if test -f $usersubname.f - then - usersubname=$usersubname.f - elif test -f $usersubname.F - then - usersubname=$usersubname.F - elif test -f $usersubname.f90 - then - usersubname=$usersubname.f90 - elif test -f $usersubname.F90 - then - usersubname=$usersubname.F90 - fi - fi - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - echo - echo warning: the option -au is no longer supported and will be ignored - echo - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_intelmpi.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi -if test "$iam" = sim ; then - SFLIB="-L$SFMATDIR -lMBA_Grain" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$usersubname" - then - if test ! -f $usersubname - then - error="$error -user subroutine file $usersubname not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" - fi -fi - -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $usersubname -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $usersubname -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($usersubname)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user - basefile=`$BASENAME $value` - if test ${basefile##*.} = f - then - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user.f - elif test ${basefile##*.} = F - then - user=`dirname $value`/`$BASENAME $value .F` - usersubname=$user.F - elif test ${basefile##*.} = f90 - then - user=`dirname $value`/`$BASENAME $value .f90` - usersubname=$user.f90 - elif test ${basefile##*.} = F90 - then - user=`dirname $value`/`$BASENAME $value .F90` - usersubname=$user.F90 - fi - case $user in - \/*) - ;; - *) - user=`pwd`/$user - usersubname=`pwd`/$usersubname - ;; - esac - if test ! -f $usersubname - then - if test -f $usersubname.f - then - usersubname=$usersubname.f - elif test -f $usersubname.F - then - usersubname=$usersubname.F - elif test -f $usersubname.f90 - then - usersubname=$usersubname.f90 - elif test -f $usersubname.F90 - then - usersubname=$usersubname.F90 - fi - fi - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# - - if test "$user" - then -# program=$user.marc - program=$DIRJOB/`$BASENAME $user .f`.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$DIRJOB/`$BASENAME $user .f`.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -# -# check for external file to run using valgrind -# -if test -f $MARC_TOOLS/run_marc_valgrind -then - . $MARC_TOOLS/run_marc_valgrind -fi - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$DIRJOB/`$BASENAME $user .f`.o - basefile=`$BASENAME $usersubname` - if test ${basefile##*.} = f - then - usersub=$DIRJOB/`$BASENAME $user .f`.F - ln -sf "$user.f" "$usersub" - else - usersub=$usersubname - fi - - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test ${basefile##*.} = f - then - ln -sf "$user.f" "$usersub" - fi - if test $MACHINENAME = "CRAY" - then - $FORTRAN $usersub || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $FORTRAN $usersub -o $userobj || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - if test ${basefile##*.} = f - then - /bin/rm -f "$usersub" - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $SRCLIB \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $SFLIB \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=`basename $usersubname .f` - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user.f $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user.f on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser.f 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user.f on host `hostname`" - fi - userobj=$DIRJOB/`$BASENAME $user .f`.o - basefile=`$BASENAME $usersubname` - if test ${basefile##*.} = f - then - usersub=$DIRJOB/`$BASENAME $user .f`.F - ln -sf "$user.f" "$usersub" - else - usersub=$usersubname - fi - if test $MACHINENAME = "CRAY" - then - $FORTRAN $usersub || \ - { - echo "$0: compile failed for $user.f" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $FORTRAN $usersub -o $userobj || \ - { - echo "$0: compile failed for $user.f" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - if test ${basefile##*.} = f - then - /bin/rm -f "$usersub" - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $SRCLIB \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $SFLIB \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$BINDIR/exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi - fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=`basename $usersubname .f` - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user.f $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user.f on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser.f 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user.f on host `hostname`" - fi - userobj=$DIRJOB/`$BASENAME $user .f`.o - basefile=`$BASENAME $usersubname` - if test ${basefile##*.} = f - then - usersub=$DIRJOB/`$BASENAME $user .f`.F - ln -sf "$user.f" "$usersub" - else - usersub=$usersubname - fi - if test $MACHINENAME = "CRAY" - then - $FORTRAN $usersub || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $FORTRAN $usersub -o $userobj || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - if test ${basefile##*.} = f - then - /bin/rm -f "$usersub" - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $SRCLIB \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $SFLIB \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null - -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$BINDIR/exeddm $RUN_JOB -ddm $ddm_arc " -fi - -$RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi - fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=`basename $usersubname .f` - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2019.1/Mentat_bin/edit_window b/installation/mods_MarcMentat/2019.1/Mentat_bin/edit_window deleted file mode 100644 index b732a7694..000000000 --- a/installation/mods_MarcMentat/2019.1/Mentat_bin/edit_window +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -# This script opens a window running an editor. -# The command to invoke the editor is specified during DAMASK installation - -%EDITOR% $* \ No newline at end of file diff --git a/installation/mods_MarcMentat/2019.1/Mentat_bin/edit_window.original b/installation/mods_MarcMentat/2019.1/Mentat_bin/edit_window.original deleted file mode 100644 index 64c0a68d0..000000000 --- a/installation/mods_MarcMentat/2019.1/Mentat_bin/edit_window.original +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh -# This script opens a window running an editor. The default window is an -# xterm, and the default editor is vi. These may be customized. - -dir= -for d in /usr/bin /usr/bin/X11; do - if test -x "$d/xterm"; then - dir="$d" - break - fi -done - -if test -z "$dir"; then - echo "$0: Could not find xterm" - exit 1 -fi - -"$dir/xterm" -T "vi $*" -n "vi $*" -e vi $* diff --git a/installation/mods_MarcMentat/2019.1/Mentat_bin/kill1.original b/installation/mods_MarcMentat/2019.1/Mentat_bin/kill1.original deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2019.1/Mentat_bin/kill1.original +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2019.1/Mentat_bin/kill4 b/installation/mods_MarcMentat/2019.1/Mentat_bin/kill4 deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2019.1/Mentat_bin/kill4 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2019.1/Mentat_bin/kill5 b/installation/mods_MarcMentat/2019.1/Mentat_bin/kill5 deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2019.1/Mentat_bin/kill5 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2019.1/Mentat_bin/kill6 b/installation/mods_MarcMentat/2019.1/Mentat_bin/kill6 deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2019.1/Mentat_bin/kill6 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2019.1/Mentat_bin/submit1.original b/installation/mods_MarcMentat/2019.1/Mentat_bin/submit1.original deleted file mode 100644 index 8007af076..000000000 --- a/installation/mods_MarcMentat/2019.1/Mentat_bin/submit1.original +++ /dev/null @@ -1,189 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=/tmp/msc/marc2019.1 -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -copy_datfile="-ci $4" -copy_postfile="-cr $5" -scr_dir=$6 -dcoup=$7 -assem_recov_nthread=$8 -nthread=$9 -shift 9 # cannot use $10, $11, ... -nsolver=$1 -mode=$2 -gpu=$3 - -if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then - slv="-iam sfm" -fi -if [ "$slv" == "marc" ]; then - slv="" -fi -if [ "$slv" == "datfit" ]; then - slv="-iam datfit" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_marc" $slv -j $job -v n -b y $nprocds $nprocd \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2019.1/Mentat_bin/submit4 b/installation/mods_MarcMentat/2019.1/Mentat_bin/submit4 deleted file mode 100644 index 55e3bcf03..000000000 --- a/installation/mods_MarcMentat/2019.1/Mentat_bin/submit4 +++ /dev/null @@ -1,191 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=%INSTALLDIR%/marc%VERSION% - -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -copy_datfile="-ci $4" -copy_postfile="-cr $5" -scr_dir=$6 -dcoup=$7 -assem_recov_nthread=$8 -nthread=$9 -shift 9 # cannot use $10, $11, ... -nsolver=$1 -mode=$2 -gpu=$3 - -if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then - slv="-iam sfm" -fi -if [ "$slv" = "marc" ]; then - slv="" -fi -if [ "$slv" = "datfit" ]; then - slv="-iam datfit" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile=${srcfile%.*}".marc" - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_damask_hmp" $slv -j $job -v n -b y $nprocds $nprocd \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2019.1/Mentat_bin/submit5 b/installation/mods_MarcMentat/2019.1/Mentat_bin/submit5 deleted file mode 100644 index 8699cf076..000000000 --- a/installation/mods_MarcMentat/2019.1/Mentat_bin/submit5 +++ /dev/null @@ -1,191 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=%INSTALLDIR%/marc%VERSION% - -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -copy_datfile="-ci $4" -copy_postfile="-cr $5" -scr_dir=$6 -dcoup=$7 -assem_recov_nthread=$8 -nthread=$9 -shift 9 # cannot use $10, $11, ... -nsolver=$1 -mode=$2 -gpu=$3 - -if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then - slv="-iam sfm" -fi -if [ "$slv" = "marc" ]; then - slv="" -fi -if [ "$slv" = "datfit" ]; then - slv="-iam datfit" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile=${srcfile%.*}".marc" - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_damask_mp" $slv -j $job -v n -b y $nprocds $nprocd \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2019.1/Mentat_bin/submit6 b/installation/mods_MarcMentat/2019.1/Mentat_bin/submit6 deleted file mode 100644 index a0179482f..000000000 --- a/installation/mods_MarcMentat/2019.1/Mentat_bin/submit6 +++ /dev/null @@ -1,191 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=%INSTALLDIR%/marc%VERSION% - -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -copy_datfile="-ci $4" -copy_postfile="-cr $5" -scr_dir=$6 -dcoup=$7 -assem_recov_nthread=$8 -nthread=$9 -shift 9 # cannot use $10, $11, ... -nsolver=$1 -mode=$2 -gpu=$3 - -if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then - slv="-iam sfm" -fi -if [ "$slv" = "marc" ]; then - slv="" -fi -if [ "$slv" = "datfit" ]; then - slv="-iam datfit" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile=${srcfile%.*}".marc" - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_damask_lmp" $slv -j $job -v n -b y $nprocds $nprocd \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2019.1/Mentat_menus/job_run.ms b/installation/mods_MarcMentat/2019.1/Mentat_menus/job_run.ms deleted file mode 100644 index 5a6d6b1a8..000000000 --- a/installation/mods_MarcMentat/2019.1/Mentat_menus/job_run.ms +++ /dev/null @@ -1,2750 +0,0 @@ -#ifndef AUTOFORGE -popmenu job_title_pm file jobs.ms -popdown job_title_ok file jobs.ms - -group user_domains_gr file domain_decomposition.ms -group user_domains_generate_gr file domain_decomposition.ms -group user_domains_tail_gr file domain_decomposition.ms -group matrix_solver_gr file job_common.ms -popmenu ddm_options file job_common.ms - -browser edit_browser file file.ms -browser directory_browser file file.ms -screen domains file domain_decomposition.ms - - - - browser usersub_file_browser { - position 0 0 - size 82 72 - text "$usersub_file_browser_label" ($usersub_file_browser_label) - filter "*.f *.F *.f90 *.F90" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$usersub_file_browser_command" ($usersub_file_browser_command) - } - - - - browser host_file_browser { - position 0 0 - size 82 72 - text "$host_file_browser_label" ($host_file_browser_label) - filter "*" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$host_file_browser_command" ($host_file_browser_command) - } - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_popmenu { - - text "RUN JOB" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - button { - position 1 9 - size 24 4 - text "USER SUBROUTINE FILE" - browser usersub_file_browser - settext $usersub_file_browser_label "SELECT USER SUBROUTINE FILE" - set $usersub_file_browser_command "*job_usersub_file" - help job_usersub_file - } - - toggle { - position +26 = - size 22 4 - text "SELECTED USER SUBS" - toggle job_usersubs - help job_run_seluser - visible job_usersubs - popmenu job_usersub_pm - } - - display { - position 1 +4 - size 50 4 - display job_usersub_file - } - - button { - position 1 +4 - size 12 4 - text "EDIT" - command "*job_edit_usersub_file" - visible job_usersub_file - } - - button { - position +12 = - size 12 4 - text "CLEAR" - command "*job_clear_usersub_file" - visible job_usersub_file - } - - roller { - position +12 = - size 26 4 - nvalues 3 - texts "COMPILE / NO SAVE" - "COMPILE AND SAVE" - "RUN SAVED EXECUTABLE" - help job_run_compile - roller "job_option user_source" - visible job_usersub_file - commands "*job_option user_source:compile_nosave" - "*job_option user_source:compile_save" - "*job_option user_source:run_saved" - } - - button { - position 1 +6 - size 24 4 - text "SOLVER/PARALLELIZATION" - help job_run_parallel - popmenu job_run_parallelization_pm - set $popname2 "job_run_parallelization_pm" - } - frame { - position 1 +4 - size 48 16 - border_width 1 - border_color black - - group{ - layout hbox - frame { - position 0 0 - size 24 16 - group { - layout vbox - - display { - position 0 0 - size 24 4 - display job_solver_solution - } - - display { - position = +4 - size 24 4 - display job_solver_type - } - spacer { - stretch 1 - } - - } - } - - frame { - position +22 = - size 24 16 - border_width 1 - border_color black - - group { - #layout vbox - display { - position = +4 - size 24 4 - display job_ddm_domains - } - - display { - position = +4 - size 24 4 - display job_assem_recov_nthreads - } - - display { - position = +4 - size 24 4 - display job_solver_procs - visible solver_allows_multi_procs - } - - display { - position = = - size 24 4 - display job_solver_threads - visible "and(solver_allows_multi_threads,\ - not(and(job_solver_mfront_sparse,\ - *job_option parallel:on)))" - } - - display { - position = +4 - size 24 4 - display job_solver_gpu - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } - } - } - } - } - - button { - position 1 +18 - size 8 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - -# see also job_common.ms -# see also the ADVANCED JOB SUBMISSION popmenu in this file - - label { - position +10 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - button { - position +20 = - size 13 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position 1 +6 - size 16 6 - text "SUBMIT (1)" - command "*submit_job 1 *monitor_job" - } - - button { - position +16 = - size 16 6 - text "ADVANCED JOB SUBMISSION" - popmenu job_submit_adv_pm - } - - button { - position +16 = - size 18 6 - text "DAMASK" - popmenu damask - } - - button { - position 1 +6 - size 16 6 - text "UPDATE" - command "*update_job" - } - - button { - position +16 = - size 16 6 - text "MONITOR" - command "*monitor_job" - } - - button { - position +16 = - size 18 6 - text "KILL" - command "*kill_job *monitor_job" - } - - label { - position 1 +7 - size 32 4 - text "STATUS" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_status" - } - - label { - position -32 +4 - size 32 4 - text "CURRENT INCREMENT (CYCLE)" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_increment" - } - - label { - position -32 +4 - size 32 4 - text "SINGULARITY RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_singularity_ratio" - } - - label { - position -32 +4 - size 32 4 - text "CONVERGENCE RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_convergence_ratio" - } - - label { - position 1 +4 - size 32 4 - text "ANALYSIS TIME" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_analysis_time" - } - - label { - position -32 +4 - size 32 4 - text "WALL TIME" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_time" - } - - frame { - position 1 +4 - size 50 8 - - group { - - frame { - position 0 0 - size 50 8 - text "TOTAL" - border_width 1 - border_color black - group { - - label { - position +6 = - size 13 4 - text "CYCLES" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_cycles" - border_width 1 - border_color black - } - - label { - position -13 +4 - size 13 4 - text "SEPARATIONS" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_separations" - border_width 1 - border_color black - } - - label { - position +10 -4 - size 11 4 - text "CUT BACKS" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_cut_backs" - border_width 1 - border_color black - } - - label { - position -11 +4 - size 11 4 - text "REMESHES" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_remeshes" - border_width 1 - border_color black - } - } - } - } - } - - label { - position 1 +8 - size 19 4 - text "EXIT NUMBER" - border_width 1 - border_color black - } - - integer { - position +19 = - size 10 4 - display "job_exit" - } - - button { - position +10 = - size 21 4 - text "EXIT MESSAGE" - popmenu job_exit_msg_pm - help exit_message - } - - label { - position 1 +6 - size 7 4 - text "EDIT" - border_width 1 - border_color black - } - - button { - position +7 = - size 12 4 - text "OUTPUT FILE" - command "*job_edit_output" - } - - button { - position +12 = - size 9 4 - text "LOG FILE" - command "*job_edit_log_file" - } - - button { - position +9 = - size 12 4 - text "STATUS FILE" - command "*job_edit_status_file" - } - - button { - position +12 = - size 10 4 - text "ANY FILE" - settext $edit_browser_label "EDIT FILE" - set $edit_browser_command "*edit_file" - browser edit_browser - help edit_file - } - - popdown { - position 1 +6 - size 32 4 - text "OPEN POST FILE (MODEL PLOT RESULTS MENU)" - command "@popdown(job_properties_pm) @main(results) @popup(modelplot_pm) *post_open_default" - } - - button { - position 1 +6 - size 12 8 - text "RESET" - command "*job_submit_reset" - } - - popdown { - position +38 = - size 12 8 - text "OK" - } - } - - window job_run_wi { - parent mentat - origin 35 1 - size 52 115 - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_usersub_pm { - - text "CURRENTLY SELECTED USER SUBROUTINES" - - group { - - - display { - position 1 +5 - size 64 86 - display "job_usersubs" - } - - popdown { - position 27 +88 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 66 102 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_submit_adv_pm { - - text "ADVANCED JOB SUBMISSION" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - label { - position 1 9 - size 19 4 - text "INITIAL ALLOCATION" - border_width 1 - border_color black - } - label { - position +19 = - size 15 4 - text "GENERAL MEMORY" - help job_param_general_init_allocation - } - text { - position +15 = - size 10 4 - display "job_param_value_general_init_allocation" - command "*job_param general_init_allocation" - help job_param_general_init_allocation - } - - label { - position +10 = - size 4 4 - text "MB" - border_width 1 - border_color black - } - - toggle { - position 1 +5 - size 32 4 - text "OUT-OF-CORE ELEMENT STORAGE" - help job_param_elsto - toggle "*job_option elsto:on" - true_command "*job_option elsto:on" - false_command "*job_option elsto:off" - } - - toggle { - position 1 +4 - size 32 4 - text "OUT-OF-CORE INCREMENTAL BACKUP" - help job_param_inc_backup_storage - toggle "*job_option inc_backup_storage:out_of_core" - true_command "*job_option inc_backup_storage:out_of_core" - false_command "*job_option inc_backup_storage:in_core" - } - - toggle { - position +34 = - size 14 4 - text "CHECK SIZES" - help job_run_check - toggle "*job_option check:on" - true_command "*job_option check:on" - false_command "*job_option check:off" - } - - frame { - position 1 +6 - size 48 12 - text "MARC INPUT FILE" - border_width 1 - border_color black - - group { - - label { - position 0 4 - size 9 4 - text "VERSION" - border_width 1 - border_color black - } - - roller { - position +9 = - size 14 4 - nvalues 28 - nvisible 28 - texts "DEFAULT" -#if 0 - "2019.1" -#endif - "2019" - "2018.1" - "2018" - "2017.1" - "2017" - "2016" - "2015" - "2014.2" - "2014.1" - "2014" - "2013.1" - "2013" - "2012" - "2011" - "2010.2" - "2010" - "2008" - "2007" - "2005R3" - "2005" - "2003" - "2001" - "2000" -#if 0 - "8" -#endif - "K7" - "K6.2" - "K5" - "K4" - help job_param_version - rollers "job_input_version_default" -#if 0 - "job_input_version_2019.1" -#endif - "job_input_version_2019" - "job_input_version_2018.1" - "job_input_version_2018" - "job_input_version_2017.1" - "job_input_version_2017" - "job_input_version_2016" - "job_input_version_2015" - "job_input_version_2014.2" - "job_input_version_2014.1" - "job_input_version_2014" - "job_input_version_2013.1" - "job_input_version_2013" - "job_input_version_2012" - "job_input_version_2011" - "job_input_version_2010.2" - "job_input_version_2010" - "job_input_version_2008" - "job_input_version_2007" - "job_input_version_2005r3" - "job_input_version_2005" - "job_input_version_2003" - "job_input_version_2001" - "job_input_version_2000" -#if 0 - "job_input_version_8" -#endif - "job_input_version_k7" - "job_input_version_k6" - "job_input_version_k5" - "job_input_version_k4" - commands "*job_option version:default" -#if 0 - "*job_option version:2019.1" -#endif - "*job_option version:2019" - "*job_option version:2018.1" - "*job_option version:2018" - "*job_option version:2017.1" - "*job_option version:2017" - "*job_option version:2016" - "*job_option version:2015" - "*job_option version:2014.2" - "*job_option version:2014.1" - "*job_option version:2014" - "*job_option version:2013.1" - "*job_option version:2013" - "*job_option version:2012" - "*job_option version:2011" - "*job_option version:2010.2" - "*job_option version:2010" - "*job_option version:2008" - "*job_option version:2007" - "*job_option version:2005r3" - "*job_option version:2005" - "*job_option version:2003" - "*job_option version:2001" - "*job_option version:2000" -#if 0 - "*job_option version:8" -#endif - "*job_option version:k7" - "*job_option version:k6" - "*job_option version:k5" - "*job_option version:k4" - visibles "job_allows_input_version_default" -#if 0 - "job_allows_input_version_2019.1" -#endif - "job_allows_input_version_2019" - "job_allows_input_version_2018.1" - "job_allows_input_version_2018" - "job_allows_input_version_2017.1" - "job_allows_input_version_2017" - "job_allows_input_version_2016" - "job_allows_input_version_2015" - "job_allows_input_version_2014.2" - "job_allows_input_version_2014.1" - "job_allows_input_version_2014" - "job_allows_input_version_2013.1" - "job_allows_input_version_2013" - "job_allows_input_version_2012" - "job_allows_input_version_2011" - "job_allows_input_version_2010.2" - "job_allows_input_version_2010" - "job_allows_input_version_2008" - "job_allows_input_version_2007" - "job_allows_input_version_2005r3" - "job_allows_input_version_2005" - "job_allows_input_version_2003" - "job_allows_input_version_2001" - "job_allows_input_version_2000" -#if 0 - "job_allows_input_version_8" -#endif - "job_allows_input_version_k7" - "job_allows_input_version_k6" - "job_allows_input_version_k5" - "job_allows_input_version_k4" - } - -# see also job_common.ms -# see also the RUN JOB popmenu in this file - - label { - position +14 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - toggle { - position 0 +4 - size 24 4 - text "EXTENDED PRECISION" - help job_run_precision - toggle "*job_option inp_file_prec:extended" - true_command "*job_option inp_file_prec:extended" - false_command "*job_option inp_file_prec:normal" - } - toggle { - position +24 = - size 24 4 - text "INCLUDE UNUSED TABLES" - toggle "*job_option input_file_tables:all" - true_command "*job_option input_file_tables:all" - false_command "*job_option input_file_tables:used" - } - } - } - - button { - position 1 +14 - size 24 4 - text "SCRATCH DIRECTORY" - settext $directory_browser_label "JOB SCRATCH DIRECTORY" - set $directory_browser_command "*job_scratch_directory" - browser directory_browser - help job_scratch_directory - } - - button { - position +24 = - size 24 4 - text "CLEAR" - command "*job_clear_scratch_directory" - visible job_scratch_directory - } - - text { - position 1 +4 - size 48 4 - display job_scratch_dir - command "*job_scratch_directory" - } - -#ifdef DCOM - toggle { - position 1 +6 - size 8 4 - text "\{DCOM}" - toggle "*job_option dcom:on" - help job_run_dcom - true_command "*job_option dcom:on" - false_command "*job_option dcom:off" - visible win32_available - } - - button { - position +8 = - size 12 4 - text "HOSTNAME" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } - - text job_dcom_hostname { - position +12 = - size 28 4 - display "job_dcom_hostname" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } -#endif - - button { - position 1 +6 - size 24 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - - button { - position +24 = - size 24 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position +4 +6 - size 20 4 - text "WRITE INPUT FILE" - command "*job_write_input" - } - - button { - position = +4 - size 20 4 - text "EDIT INPUT FILE" - command "*job_edit_input" - } - - popdown { - position 1 +5 - size 20 6 - text "SUBMIT 1" - command "*submit_job 1 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 1" - command "*execute_job 1 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 2" - command "*submit_job 2 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 2" - command "*execute_job 2 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 3" - command "*submit_job 3 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 3" - command "*execute_job 3 *monitor_job" - } - - popdown { - position 19 +8 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 -#ifdef DCOM - size 50 100 -#else - size 50 94 -#endif - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - -#-------------------------------------------------------------------------------------------------- -popmenu damask { - -#ifdef QT_MENTAT - text "DAMASK.MPIE.DE" -#endif - - group { -#ifndef QT_MENTAT - label { - position 0 0 - size 50 4 - text "DAMASK.MPIE.DE" - } -#endif - - label { - position 1 6 - size 13 6 - text "Optimzation" - border_width 1 - border_color black - } - - label { - position +13 = - size 20 6 - text "write Input" - border_width 1 - border_color black - } - - label { - position +18 = - size 30 6 - text "do not write Inp." - border_width 1 - border_color black - } - - label { - position -32 +6 - size 12 6 - text "O2 / OpenMP" - border_width 1 - border_color black - } - - popdown { - position +12 = - size 20 6 - text "Submit" - command "*submit_job 4 *monitor_job" - } - - popdown { - position +20 = - size 20 6 - text "Execute" - command "*execute_job 4 *monitor_job" - } - - label { - position -32 +6 - size 12 6 - text "O1 / OpenMP" - border_width 1 - border_color black - } - - popdown { - position +12 = - size 20 6 - text "Submit" - command "*submit_job 5 *monitor_job" - } - - popdown { - position +20 = - size 20 6 - text "Execute" - command "*execute_job 5 *monitor_job" - } - - label { - position -32 +6 - size 12 6 - text "O0 / OpenMP" - border_width 1 - border_color black - } - - popdown { - position +12 = - size 20 6 - text "Submit" - command "*submit_job 6 *monitor_job" - } - - popdown { - position +20 = - size 20 6 - text "Execute" - command "*execute_job 6 *monitor_job" - } - - popdown { - position 19 +8 - size 12 8 - text "CANCEL" - } -} - - window { - parent mentat - origin 38 8 -#ifdef DCOM - size 50 100 -#else - size 50 94 -#endif - background_color body - border_width 1 - border_color border - buffering single - } - mode permanent -} - -#-------------------------------------------------------------------------------------------------- -popmenu job_exit_msg_pm { - - text "EXIT MESSAGE" - - group { - - - - text { - position 1 5 - size 84 74 - multiline - readonly - display "job_exit_msg" - } - - popdown { - position 37 +76 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 86 90 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_parallelization_pm { - - text "SOLVER/PARALLELIZATION" - - group { - layout vbox - frame { - position 0 0 - size 42 8 - group { - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 36 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 36 4 - display job_class_label - } - } - } - frame { - position 0 8 - size 42 20 - group job_ddm_gr - text "DOMAIN DECOMPOSITION" - border_width 1 - border_color black - } - - frame { - position 0 +20 - size 42 13 - group job_assem_recov_gr - text "ASSEMBLY AND RECOVERY" - border_width 1 - border_color black - } - - frame { - position 0 +14 - size 42 31 - group job_parallel_matrix_solver_gr - text "MATRIX SOLVER" - border_width 1 - border_color black - } - - frame { - position 0 +32 - size 42 28 - group job_parallel_env_gr - text "PARALLELIZATION ENVIRONMENT" - border_width 1 - border_color black - visible "or(*job_option parallel:on, \ - solver_multi_procs)" - } - frame { - position 15 +30 - size 42 8 - group { - layout hbox - - spacer { - stretch 1 - } - popdown { - position 15 0 - size 12 8 - text "OK" - } - spacer { - stretch 1 - } - } - } - - spacer { - spacing 2 - stretch 1 - } - } - - window { - parent mentat - origin 38 1 - size 60 119 - background_color body - border_width 1 - border_color border - buffering single - } - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_gr { - - toggle { - position 1 4 - size 42 4 - text "USE \{DDM}" - toggle "*job_option parallel:on" - help job_run_ddm_use - true_command "*job_option parallel:on" - false_command "*job_option parallel:off" - active "and(not(job_solver_it_ext),\ - not(job_solver_mixed_direct_iterative))" - } - - frame { - position = +5 - size 42 4 - group job_ddm_use_gr - visible "*job_option parallel:on" - } -} - -group job_ddm_use_gr { - layout vbox - frame{ - position 0 0 - size 30 4 - group { - layout hbox - label { - position 0 0 - size 12 4 - text "DECOMPOSITION IN" - help job_run_ddm_generator - } - oneonly{ - position +12 = - size 8 4 - text "MARC" - oneonly "*job_option ddm_generator:fea_solver" - command "*job_option ddm_generator:fea_solver" - help job_run_ddm_generator - } - oneonly{ - position +12 = - size 8 4 - text "MENTAT" - oneonly "*job_option ddm_generator:preprocessor" - command "*job_option ddm_generator:preprocessor" - help job_run_ddm_generator - } - } - } - - frame { - position 0 +5 - size 44 8 - group job_ddm_fea_solver_gr - visible "*job_option ddm_generator:fea_solver" - } - - frame { - position = = - size 44 8 - group job_ddm_preprocessor_gr - visible "*job_option ddm_generator:preprocessor" - } - - frame{ - position 0 +5 - size 40 4 - group{ - layout hbox - text { - position 0 0 - size 22 4 - text "Single Input File" - readonly - visible "*job_option ddm_generator:fea_solver" - } - - roller { - position = = - size 22 4 - nvalues 2 - texts "MULTIPLE INPUT FILES" - "SINGLE INPUT FILE" - roller "job_option ddm_single_input" - commands "*job_option ddm_single_input:off" - "*job_option ddm_single_input:on" - visible "*job_option ddm_generator:preprocessor" - help job_run_ddm_single_input - } - - roller { - position +23 = - size 21 4 - nvalues 2 - texts "MULTIPLE POST FILES" - "SINGLE POST FILE" - roller "job_option ddm_single_post" - commands "*job_option ddm_single_post:off" - "*job_option ddm_single_post:on" - help job_run_ddm_single_post - } - } - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_fea_solver_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - help job_param - } - - text { - position +10 = - size 4 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 0 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - button { - position +18 = - size 12 4 - text "ADV. SETTINGS" - popmenu job_ddm_fea_solver_pm - } -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_ddm_fea_solver_pm { - - text "JOB PARALLELIZATION" - - group { - units 32 120 - - - label { - position 0 5 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - frame { - - position 0 +9 - size 32 76 - text "ADVANCED DECOMPOSITION IN MARC" - border_width 1 - border_color black - - group { - - label { - position 1 4 - size 16 4 - text "# DOMAINS" - help job_param - } - - text { - position +16 = - size 14 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 1 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 23 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - frame { - position 1 +5 - size 30 20 - group job_ddm_direction_gr - visible "or(*job_option ddm_method:vector, \ - *job_option ddm_method:radial, \ - *job_option ddm_method:angular)" - } - - toggle { - position 1 +21 - size 30 4 - text "DOMAIN ISLAND REMOVAL" - toggle "*job_option ddm_island_removal:on" - true_command "*job_option ddm_island_removal:on" - false_command "*job_option ddm_island_removal:off" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "GRAPH" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "COARSE" - "FINE" - help ddm_decomp_coarse_graph - rollers "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - commands "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "QUADRATIC ELEMENTS" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "GENUINE" - "LINEARIZED" - help job_run_ddm_decomp_linearized - rollers "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - commands "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - } - - label { - position 1 +5 - size 15 4 - text "ELEMENT WEIGHT FACTOR" - help job_param - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_elem_weight_factor" - command "*job_param ddm_elem_weight_factor" - help job_run_ddm_decomp_element_weight_factor - } - - toggle { - position 1 +5 - size 30 4 - text "DETECT CONTACT" - toggle "*job_option ddm_detect_contact:on" - true_command "*job_option ddm_detect_contact:on" - false_command "*job_option ddm_detect_contact:off" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - help job_run_ddm_decomp_detect_contact - } - - label { - position = +5 - size 15 4 - text "CONTACT TOLERANCE" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - command "*set_ddm_contact_tolerance" - display "job_param_value_ddm_contact_tolerance" - command "*job_param ddm_contact_tolerance" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_tolerance - } - - label { - position -15 +4 - size 15 4 - text "CONTACT CONSTR FACTOR" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_contact_constr_factor" - command "*job_param ddm_contact_constr_factor" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_constraint_factor - } - } - } - - popdown { - position 0 +77 - size 32 8 - text "OK" - } - } - mode permanent -} # job_ddm_fea_solver_pm - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_direction_gr { - - button { - position 0 0 - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "*job_option ddm_method:vector" - } - - button { - position = = - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "not(*job_option ddm_method:vector)" - } - - button { - position +15 = - size 15 4 - text "FROM / TO" - command "*job_vector_from_to ddm_sort_direction_x" - } - - text { - position -15 +4 - size 10 4 - command "*job_param ddm_sort_direction_x" - display "job_param_value_ddm_sort_direction_x" - help ddm_job_decomp_user_direction_x - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_y" - display "job_param_value_ddm_sort_direction_y" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_z" - display "job_param_value_ddm_sort_direction_z" - } - - frame { - position 0 +4 - size 30 8 - group job_ddm_sort_point_gr - visible "not(*job_option ddm_method:vector)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_sort_point_gr { - - label { - position 0 0 - size 14 4 - border_width 1 - border_color black - text "POINT ON AXIS" - } - - roller { - position +14 = - size 10 4 - nvalues 2 - texts "DEFAULT" - "USER" - roller "job_option ddm_sort_point" - commands "*job_option ddm_sort_point:default" - "*job_option ddm_sort_point:user" - } - - button { - position +10 = - size 6 4 - text "SET" - command "*job_position ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position 0 +4 - size 10 4 - command "*job_param ddm_sort_point_x" - display "job_param_value_ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_y" - display "job_param_value_ddm_sort_point_y" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_z" - display "job_param_value_ddm_sort_point_z" - visible "*job_option ddm_sort_point:user" - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_preprocessor_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - border_width 1 - border_color black - } - - integer { - position +10 = - size 4 4 - display valid_domains - } - - button { - position 0 +4 - size 30 4 - text "USER DOMAINS" - popmenu domains_pm - help job_run_ddm_user_domains - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_assem_recov_gr { - - toggle { - position 1 +4 - size 30 4 - text "MULTIPLE THREADS" - true_command "*job_option assem_recov_multi_threading:on" - false_command "*job_option assem_recov_multi_threading:off" - toggle "*job_option assem_recov_multi_threading:on" - } - - label { - position = +4 - size 12 4 - text "# THREADS" - visible "*job_option assem_recov_multi_threading:on" - } - - text { - position +12 = - size 4 4 - display "job_param_value_assem_recov_nthreads" - command "*job_param assem_recov_nthreads" - visible "*job_option assem_recov_multi_threading:on" - } - - label { - position +4 = - size 10 4 - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - } - - display { - position +12 = - size 4 4 - display "job_assem_recov_nthreads_dom" - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - } - spacer{ - stretch 2 - } - -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_matrix_solver_gr { - layout vbox - frame { - position 1 0 - size 36 31 - group { - layout hbox - label { - position 3 4 - size 12 4 - text "SOLUTION" - border_width 1 - border_color black - } - oneonly { - position +12 = - size 12 4 - text "SYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_off" - command "*job_option solver_nonsym:off" - } - oneonly { - position +12 = - size 12 4 - text "NONSYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_on" - command "*job_option solver_nonsym:on" - } - spacer { - stretch 1 - } - } - } - - frame { - position 1 +5 - size 42 23 - group matrix_solver_gr - help job_param_solver - } - - frame { - position +1 = - size 42 4 - group job_run_solver_ddm_opts_gr - visible "*job_option parallel:on" - } - - frame { - position 1 +23 - size 42 8 - group job_solver_multi_procs_gr - visible solver_allows_multi_procs - } - - frame { - position = = - size 42 8 - group job_solver_multi_threads_gr - visible solver_allows_multi_threads - } - - frame { - position 1 +9 - size 42 8 - group job_solver_gpu_gr - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } - -} - - -#-------------------------------------------------------------------------------------------------- -group job_run_solver_ddm_opts_gr { - - button { - position 0 0 - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options -# see also job_common.ms! - visible "not(or(job_solver_it_sparse, \ - job_solver_it_ext, \ - job_solver_mixed_direct_iterative, \ - job_solver_pardiso,\ - job_solver_mumps))" - } - button { - position = = - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options_mumps - visible "job_solver_mumps" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_gr { - frame { - position 0 0 - size 42 8 - group job_solver_multi_procs_parallel_off_gr - visible "*job_option parallel:off" - } - - frame { - position = = - size 42 8 - group job_solver_multi_procs_parallel_on_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - true_command "*job_option nsolver_procs_serial:on" - false_command "*job_option nsolver_procs_serial:off" - toggle "*job_option nsolver_procs_serial:on" - help job_run_multithreading - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - visible "*job_option nsolver_procs_serial:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - visible "*job_option nsolver_procs_serial:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - border_width 1 - border_color black - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - help job_run_multithreading - rollers "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_nsolver_procs_ddm_automatic_gr - visible "*job_option nsolver_procs_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_nsolver_procs_ddm_user_gr - visible "*job_option nsolver_procs_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - } -} - -group job_solver_multi_threads_gr { - layout vbox - spacing 0 - - frame { - size 46 8 - group job_solver_multi_threads_it_sparse_parallel_off_gr - visible "and(job_solver_it_sparse,*job_option parallel:off)" - } - - frame { - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_off_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:off)" - } - - frame { - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_on_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:on)" - } - - frame { - size 46 8 - group job_solver_multi_threads_pardiso_parallel_off_gr - visible "and(job_solver_pardiso,*job_option parallel:off)" - } - - frame { - size 46 8 - group job_solver_multi_threads_pardiso_parallel_on_gr - visible "and(job_solver_pardiso,*job_option parallel:on)" - } - - frame { - size 46 8 - group job_solver_multi_threads_it_ext_off_gr - visible "and(job_solver_it_ext,*job_option parallel:off)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_it_sparse_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option it_sparse_multi_threading:on" - true_command "*job_option it_sparse_multi_threading:on" - false_command "*job_option it_sparse_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option it_sparse_multi_threading:on" - help job_run_multithreading - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option it_sparse_multi_threading:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option mfront_sparse_multi_threading:on" - true_command "*job_option mfront_sparse_multi_threading:on" - false_command "*job_option mfront_sparse_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option mfront_sparse_multi_threading:on" - help job_run_multithreading - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option mfront_sparse_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +30 0 - size 12 4 - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - help job_run_multithreading - } - - display { - position +12 0 - size 4 4 - display "job_mfront_sparse_nthreads_dom" - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - } - - label { - position 0 +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - help job_run_multithreading - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_automatic_gr - visible "*job_option mfront_sparse_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_user_gr - visible "*job_option mfront_sparse_multi_threading_ddm:user" - } -} -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_run_multithreading - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - - - -#-------------------------------------------------------------------------------------------------- -group job_solver_gpu_gr { - - toggle { - position 0 0 - size 30 4 - text "USE \{GPU(s)}" - toggle "*job_option solver_use_gpu:on" - true_command "*job_option solver_use_gpu:on" - false_command "*job_option solver_use_gpu:off" - help job_solver_gpu - } - frame{ - position 0 +4 - size 28 4 - group{ - layout hbox - - label { - position 0 0 - size 16 4 - text "\{GPU} SELECTION" - border_width 1 - border_color black - visible "*job_option solver_use_gpu:on" - } - - roller { - position +16 = - size 12 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - rollers "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - visible "*job_option solver_use_gpu:on" - help job_solver_gpu - } - - text { - position +12 = - size 12 4 - display job_solver_gpus - command "*clear_job_solver_gpus *job_solver_gpus" - visible "and(*job_option solver_use_gpu:on,*job_option solver_gpus:user)" - } - spacer { - stretch 1 - } - } - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option pardiso_multi_threading:on" - true_command "*job_option pardiso_multi_threading:on" - false_command "*job_option pardiso_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option pardiso_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option pardiso_multi_threading:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position = +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_pardiso_multi_threads_ddm_automatic_gr - visible "*job_option pardiso_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_pardiso_multi_threads_ddm_user_gr - visible "*job_option pardiso_multi_threading_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_it_ext_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option it_ext_multi_threading:on" - true_command "*job_option it_ext_multi_threading:on" - false_command "*job_option it_ext_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option it_ext_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option it_ext_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_gr { - - frame{ - position 0 +4 - size 40 4 - group{ - layout hbox - label{ - position 0 0 - size 8 4 - text "SETUP" - help job_run_ddm_setup - } - oneonly { - position +12 = - size 12 4 - text "SINGLE MACHINE" - oneonly "*job_option parallel_setup:single" - command "*job_option parallel_setup:single" - help job_run_ddm_setup - } - oneonly { - position +8 = - size 12 4 - text "NETWORK" - oneonly "*job_option parallel_setup:network" - command "*job_option parallel_setup:network" - help job_run_ddm_setup - } - - spacer { - stretch 1 - } - } - } - - - frame { - position +1 +5 - size 40 16 - group job_parallel_env_network_gr - visible "*job_option parallel_setup:network" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_gr { - - button { - position 0 0 - size 28 4 - text "HOST FILE" - browser host_file_browser - settext $host_file_browser_label "SELECT HOST FILE" - set $host_file_browser_command "*job_host_file" - help job_host_file - } - - button { - position +28 = - size 8 4 - text "EDIT" - command "*job_edit_host_file" - help job_edit_host_file - visible job_host_file - } - - button { - position +8 = - size 8 4 - text "CLEAR" - command "*job_clear_host_file" - help job_clear_host_file - visible job_host_file - } - - display { - position 0 +4 - size 44 4 - display job_host_file - } - - frame { - position 0 +5 - size 44 9 - group job_parallel_env_network_ddm_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_ddm_gr { - - toggle { - position 0 0 - size 22 4 - text "COPY INPUT FILE" - toggle "*job_option copy_input_file:on" - true_command "*job_option copy_input_file:on" - false_command "*job_option copy_input_file:off" - help job_host_copy_inputfile - } - - toggle { - position +23 = - size 21 4 - text "COPY POST FILE" - toggle "*job_option copy_post_file:on" - true_command "*job_option copy_post_file:on" - false_command "*job_option copy_post_file:off" - help job_host_copy_inputfile - } - - label { - position 0 +5 - size 10 4 - text "HOSTS" - border_width 1 - border_color black - visible job_usersub_file - } - - roller { - position +10 = - size 18 4 - nvalues 2 - texts "COMPATIBLE" - "INCOMPATIBLE" - roller "job_option network_hosts" - commands "*job_option network_hosts:compatible" - "*job_option network_hosts:incompatible" - help job_host_comp - visible job_usersub_file - } -} - - -#endif diff --git a/installation/mods_MarcMentat/2019.1/Mentat_menus/job_run.ms.original b/installation/mods_MarcMentat/2019.1/Mentat_menus/job_run.ms.original deleted file mode 100644 index 67fe07ee5..000000000 --- a/installation/mods_MarcMentat/2019.1/Mentat_menus/job_run.ms.original +++ /dev/null @@ -1,2615 +0,0 @@ -#ifndef AUTOFORGE -popmenu job_title_pm file jobs.ms -popdown job_title_ok file jobs.ms - -group user_domains_gr file domain_decomposition.ms -group user_domains_generate_gr file domain_decomposition.ms -group user_domains_tail_gr file domain_decomposition.ms -group matrix_solver_gr file job_common.ms -popmenu ddm_options file job_common.ms - -browser edit_browser file file.ms -browser directory_browser file file.ms -screen domains file domain_decomposition.ms - - - - browser usersub_file_browser { - position 0 0 - size 82 72 - text "$usersub_file_browser_label" ($usersub_file_browser_label) - filter "*.f *.F *.f90 *.F90" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$usersub_file_browser_command" ($usersub_file_browser_command) - } - - - - browser host_file_browser { - position 0 0 - size 82 72 - text "$host_file_browser_label" ($host_file_browser_label) - filter "*" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$host_file_browser_command" ($host_file_browser_command) - } - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_popmenu { - - text "RUN JOB" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - button { - position 1 9 - size 24 4 - text "USER SUBROUTINE FILE" - browser usersub_file_browser - settext $usersub_file_browser_label "SELECT USER SUBROUTINE FILE" - set $usersub_file_browser_command "*job_usersub_file" - help job_usersub_file - } - - toggle { - position +26 = - size 22 4 - text "SELECTED USER SUBS" - toggle job_usersubs - help job_run_seluser - visible job_usersubs - popmenu job_usersub_pm - } - - display { - position 1 +4 - size 50 4 - display job_usersub_file - } - - button { - position 1 +4 - size 12 4 - text "EDIT" - command "*job_edit_usersub_file" - visible job_usersub_file - } - - button { - position +12 = - size 12 4 - text "CLEAR" - command "*job_clear_usersub_file" - visible job_usersub_file - } - - roller { - position +12 = - size 26 4 - nvalues 3 - texts "COMPILE / NO SAVE" - "COMPILE AND SAVE" - "RUN SAVED EXECUTABLE" - help job_run_compile - roller "job_option user_source" - visible job_usersub_file - commands "*job_option user_source:compile_nosave" - "*job_option user_source:compile_save" - "*job_option user_source:run_saved" - } - - button { - position 1 +6 - size 24 4 - text "SOLVER/PARALLELIZATION" - help job_run_parallel - popmenu job_run_parallelization_pm - set $popname2 "job_run_parallelization_pm" - } - frame { - position 1 +4 - size 48 16 - border_width 1 - border_color black - - group{ - layout hbox - frame { - position 0 0 - size 24 16 - group { - layout vbox - - display { - position 0 0 - size 24 4 - display job_solver_solution - } - - display { - position = +4 - size 24 4 - display job_solver_type - } - spacer { - stretch 1 - } - - } - } - - frame { - position +22 = - size 24 16 - border_width 1 - border_color black - - group { - #layout vbox - display { - position = +4 - size 24 4 - display job_ddm_domains - } - - display { - position = +4 - size 24 4 - display job_assem_recov_nthreads - } - - display { - position = +4 - size 24 4 - display job_solver_procs - visible solver_allows_multi_procs - } - - display { - position = = - size 24 4 - display job_solver_threads - visible "and(solver_allows_multi_threads,\ - not(and(job_solver_mfront_sparse,\ - *job_option parallel:on)))" - } - - display { - position = +4 - size 24 4 - display job_solver_gpu - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } - } - } - } - } - - button { - position 1 +18 - size 8 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - -# see also job_common.ms -# see also the ADVANCED JOB SUBMISSION popmenu in this file - - label { - position +10 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - button { - position +20 = - size 13 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position 1 +6 - size 16 6 - text "SUBMIT (1)" - command "*submit_job 1 *monitor_job" - } - - button { - position +16 = - size 34 6 - text "ADVANCED JOB SUBMISSION" - popmenu job_submit_adv_pm - } - - button { - position 1 +6 - size 16 6 - text "UPDATE" - command "*update_job" - } - - button { - position +16 = - size 16 6 - text "MONITOR" - command "*monitor_job" - } - - button { - position +16 = - size 18 6 - text "KILL" - command "*kill_job *monitor_job" - } - - label { - position 1 +7 - size 32 4 - text "STATUS" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_status" - } - - label { - position -32 +4 - size 32 4 - text "CURRENT INCREMENT (CYCLE)" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_increment" - } - - label { - position -32 +4 - size 32 4 - text "SINGULARITY RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_singularity_ratio" - } - - label { - position -32 +4 - size 32 4 - text "CONVERGENCE RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_convergence_ratio" - } - - label { - position 1 +4 - size 32 4 - text "ANALYSIS TIME" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_analysis_time" - } - - label { - position -32 +4 - size 32 4 - text "WALL TIME" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_time" - } - - frame { - position 1 +4 - size 50 8 - - group { - - frame { - position 0 0 - size 50 8 - text "TOTAL" - border_width 1 - border_color black - group { - - label { - position +6 = - size 13 4 - text "CYCLES" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_cycles" - border_width 1 - border_color black - } - - label { - position -13 +4 - size 13 4 - text "SEPARATIONS" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_separations" - border_width 1 - border_color black - } - - label { - position +10 -4 - size 11 4 - text "CUT BACKS" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_cut_backs" - border_width 1 - border_color black - } - - label { - position -11 +4 - size 11 4 - text "REMESHES" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_remeshes" - border_width 1 - border_color black - } - } - } - } - } - - label { - position 1 +8 - size 19 4 - text "EXIT NUMBER" - border_width 1 - border_color black - } - - integer { - position +19 = - size 10 4 - display "job_exit" - } - - button { - position +10 = - size 21 4 - text "EXIT MESSAGE" - popmenu job_exit_msg_pm - help exit_message - } - - label { - position 1 +6 - size 7 4 - text "EDIT" - border_width 1 - border_color black - } - - button { - position +7 = - size 12 4 - text "OUTPUT FILE" - command "*job_edit_output" - } - - button { - position +12 = - size 9 4 - text "LOG FILE" - command "*job_edit_log_file" - } - - button { - position +9 = - size 12 4 - text "STATUS FILE" - command "*job_edit_status_file" - } - - button { - position +12 = - size 10 4 - text "ANY FILE" - settext $edit_browser_label "EDIT FILE" - set $edit_browser_command "*edit_file" - browser edit_browser - help edit_file - } - - popdown { - position 1 +6 - size 32 4 - text "OPEN POST FILE (MODEL PLOT RESULTS MENU)" - command "@popdown(job_properties_pm) @main(results) @popup(modelplot_pm) *post_open_default" - } - - button { - position 1 +6 - size 12 8 - text "RESET" - command "*job_submit_reset" - } - - popdown { - position +38 = - size 12 8 - text "OK" - } - } - - window job_run_wi { - parent mentat - origin 35 1 - size 52 115 - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_usersub_pm { - - text "CURRENTLY SELECTED USER SUBROUTINES" - - group { - - - display { - position 1 +5 - size 64 86 - display "job_usersubs" - } - - popdown { - position 27 +88 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 66 102 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_submit_adv_pm { - - text "ADVANCED JOB SUBMISSION" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - label { - position 1 9 - size 19 4 - text "INITIAL ALLOCATION" - border_width 1 - border_color black - } - label { - position +19 = - size 15 4 - text "GENERAL MEMORY" - help job_param_general_init_allocation - } - text { - position +15 = - size 10 4 - display "job_param_value_general_init_allocation" - command "*job_param general_init_allocation" - help job_param_general_init_allocation - } - - label { - position +10 = - size 4 4 - text "MB" - border_width 1 - border_color black - } - - toggle { - position 1 +5 - size 32 4 - text "OUT-OF-CORE ELEMENT STORAGE" - help job_param_elsto - toggle "*job_option elsto:on" - true_command "*job_option elsto:on" - false_command "*job_option elsto:off" - } - - toggle { - position 1 +4 - size 32 4 - text "OUT-OF-CORE INCREMENTAL BACKUP" - help job_param_inc_backup_storage - toggle "*job_option inc_backup_storage:out_of_core" - true_command "*job_option inc_backup_storage:out_of_core" - false_command "*job_option inc_backup_storage:in_core" - } - - toggle { - position +34 = - size 14 4 - text "CHECK SIZES" - help job_run_check - toggle "*job_option check:on" - true_command "*job_option check:on" - false_command "*job_option check:off" - } - - frame { - position 1 +6 - size 48 12 - text "MARC INPUT FILE" - border_width 1 - border_color black - - group { - - label { - position 0 4 - size 9 4 - text "VERSION" - border_width 1 - border_color black - } - - roller { - position +9 = - size 14 4 - nvalues 28 - nvisible 28 - texts "DEFAULT" -#if 0 - "2019.1" -#endif - "2019" - "2018.1" - "2018" - "2017.1" - "2017" - "2016" - "2015" - "2014.2" - "2014.1" - "2014" - "2013.1" - "2013" - "2012" - "2011" - "2010.2" - "2010" - "2008" - "2007" - "2005R3" - "2005" - "2003" - "2001" - "2000" -#if 0 - "8" -#endif - "K7" - "K6.2" - "K5" - "K4" - help job_param_version - rollers "job_input_version_default" -#if 0 - "job_input_version_2019.1" -#endif - "job_input_version_2019" - "job_input_version_2018.1" - "job_input_version_2018" - "job_input_version_2017.1" - "job_input_version_2017" - "job_input_version_2016" - "job_input_version_2015" - "job_input_version_2014.2" - "job_input_version_2014.1" - "job_input_version_2014" - "job_input_version_2013.1" - "job_input_version_2013" - "job_input_version_2012" - "job_input_version_2011" - "job_input_version_2010.2" - "job_input_version_2010" - "job_input_version_2008" - "job_input_version_2007" - "job_input_version_2005r3" - "job_input_version_2005" - "job_input_version_2003" - "job_input_version_2001" - "job_input_version_2000" -#if 0 - "job_input_version_8" -#endif - "job_input_version_k7" - "job_input_version_k6" - "job_input_version_k5" - "job_input_version_k4" - commands "*job_option version:default" -#if 0 - "*job_option version:2019.1" -#endif - "*job_option version:2019" - "*job_option version:2018.1" - "*job_option version:2018" - "*job_option version:2017.1" - "*job_option version:2017" - "*job_option version:2016" - "*job_option version:2015" - "*job_option version:2014.2" - "*job_option version:2014.1" - "*job_option version:2014" - "*job_option version:2013.1" - "*job_option version:2013" - "*job_option version:2012" - "*job_option version:2011" - "*job_option version:2010.2" - "*job_option version:2010" - "*job_option version:2008" - "*job_option version:2007" - "*job_option version:2005r3" - "*job_option version:2005" - "*job_option version:2003" - "*job_option version:2001" - "*job_option version:2000" -#if 0 - "*job_option version:8" -#endif - "*job_option version:k7" - "*job_option version:k6" - "*job_option version:k5" - "*job_option version:k4" - visibles "job_allows_input_version_default" -#if 0 - "job_allows_input_version_2019.1" -#endif - "job_allows_input_version_2019" - "job_allows_input_version_2018.1" - "job_allows_input_version_2018" - "job_allows_input_version_2017.1" - "job_allows_input_version_2017" - "job_allows_input_version_2016" - "job_allows_input_version_2015" - "job_allows_input_version_2014.2" - "job_allows_input_version_2014.1" - "job_allows_input_version_2014" - "job_allows_input_version_2013.1" - "job_allows_input_version_2013" - "job_allows_input_version_2012" - "job_allows_input_version_2011" - "job_allows_input_version_2010.2" - "job_allows_input_version_2010" - "job_allows_input_version_2008" - "job_allows_input_version_2007" - "job_allows_input_version_2005r3" - "job_allows_input_version_2005" - "job_allows_input_version_2003" - "job_allows_input_version_2001" - "job_allows_input_version_2000" -#if 0 - "job_allows_input_version_8" -#endif - "job_allows_input_version_k7" - "job_allows_input_version_k6" - "job_allows_input_version_k5" - "job_allows_input_version_k4" - } - -# see also job_common.ms -# see also the RUN JOB popmenu in this file - - label { - position +14 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - toggle { - position 0 +4 - size 24 4 - text "EXTENDED PRECISION" - help job_run_precision - toggle "*job_option inp_file_prec:extended" - true_command "*job_option inp_file_prec:extended" - false_command "*job_option inp_file_prec:normal" - } - toggle { - position +24 = - size 24 4 - text "INCLUDE UNUSED TABLES" - toggle "*job_option input_file_tables:all" - true_command "*job_option input_file_tables:all" - false_command "*job_option input_file_tables:used" - } - } - } - - button { - position 1 +14 - size 24 4 - text "SCRATCH DIRECTORY" - settext $directory_browser_label "JOB SCRATCH DIRECTORY" - set $directory_browser_command "*job_scratch_directory" - browser directory_browser - help job_scratch_directory - } - - button { - position +24 = - size 24 4 - text "CLEAR" - command "*job_clear_scratch_directory" - visible job_scratch_directory - } - - text { - position 1 +4 - size 48 4 - display job_scratch_dir - command "*job_scratch_directory" - } - -#ifdef DCOM - toggle { - position 1 +6 - size 8 4 - text "\{DCOM}" - toggle "*job_option dcom:on" - help job_run_dcom - true_command "*job_option dcom:on" - false_command "*job_option dcom:off" - visible win32_available - } - - button { - position +8 = - size 12 4 - text "HOSTNAME" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } - - text job_dcom_hostname { - position +12 = - size 28 4 - display "job_dcom_hostname" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } -#endif - - button { - position 1 +6 - size 24 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - - button { - position +24 = - size 24 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position +4 +6 - size 20 4 - text "WRITE INPUT FILE" - command "*job_write_input" - } - - button { - position = +4 - size 20 4 - text "EDIT INPUT FILE" - command "*job_edit_input" - } - - popdown { - position 1 +5 - size 20 6 - text "SUBMIT 1" - command "*submit_job 1 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 1" - command "*execute_job 1 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 2" - command "*submit_job 2 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 2" - command "*execute_job 2 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 3" - command "*submit_job 3 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 3" - command "*execute_job 3 *monitor_job" - } - - popdown { - position 19 +8 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 -#ifdef DCOM - size 50 100 -#else - size 50 94 -#endif - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_exit_msg_pm { - - text "EXIT MESSAGE" - - group { - - - - text { - position 1 5 - size 84 74 - multiline - readonly - display "job_exit_msg" - } - - popdown { - position 37 +76 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 86 90 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_parallelization_pm { - - text "SOLVER/PARALLELIZATION" - - group { - layout vbox - frame { - position 0 0 - size 42 8 - group { - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 36 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 36 4 - display job_class_label - } - } - } - frame { - position 0 8 - size 42 20 - group job_ddm_gr - text "DOMAIN DECOMPOSITION" - border_width 1 - border_color black - } - - frame { - position 0 +20 - size 42 13 - group job_assem_recov_gr - text "ASSEMBLY AND RECOVERY" - border_width 1 - border_color black - } - - frame { - position 0 +14 - size 42 31 - group job_parallel_matrix_solver_gr - text "MATRIX SOLVER" - border_width 1 - border_color black - } - - frame { - position 0 +32 - size 42 28 - group job_parallel_env_gr - text "PARALLELIZATION ENVIRONMENT" - border_width 1 - border_color black - visible "or(*job_option parallel:on, \ - solver_multi_procs)" - } - frame { - position 15 +30 - size 42 8 - group { - layout hbox - - spacer { - stretch 1 - } - popdown { - position 15 0 - size 12 8 - text "OK" - } - spacer { - stretch 1 - } - } - } - - spacer { - spacing 2 - stretch 1 - } - } - - window { - parent mentat - origin 38 1 - size 60 119 - background_color body - border_width 1 - border_color border - buffering single - } - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_gr { - - toggle { - position 1 4 - size 42 4 - text "USE \{DDM}" - toggle "*job_option parallel:on" - help job_run_ddm_use - true_command "*job_option parallel:on" - false_command "*job_option parallel:off" - active "and(not(job_solver_it_ext),\ - not(job_solver_mixed_direct_iterative))" - } - - frame { - position = +5 - size 42 4 - group job_ddm_use_gr - visible "*job_option parallel:on" - } -} - -group job_ddm_use_gr { - layout vbox - frame{ - position 0 0 - size 30 4 - group { - layout hbox - label { - position 0 0 - size 12 4 - text "DECOMPOSITION IN" - help job_run_ddm_generator - } - oneonly{ - position +12 = - size 8 4 - text "MARC" - oneonly "*job_option ddm_generator:fea_solver" - command "*job_option ddm_generator:fea_solver" - help job_run_ddm_generator - } - oneonly{ - position +12 = - size 8 4 - text "MENTAT" - oneonly "*job_option ddm_generator:preprocessor" - command "*job_option ddm_generator:preprocessor" - help job_run_ddm_generator - } - } - } - - frame { - position 0 +5 - size 44 8 - group job_ddm_fea_solver_gr - visible "*job_option ddm_generator:fea_solver" - } - - frame { - position = = - size 44 8 - group job_ddm_preprocessor_gr - visible "*job_option ddm_generator:preprocessor" - } - - frame{ - position 0 +5 - size 40 4 - group{ - layout hbox - text { - position 0 0 - size 22 4 - text "Single Input File" - readonly - visible "*job_option ddm_generator:fea_solver" - } - - roller { - position = = - size 22 4 - nvalues 2 - texts "MULTIPLE INPUT FILES" - "SINGLE INPUT FILE" - roller "job_option ddm_single_input" - commands "*job_option ddm_single_input:off" - "*job_option ddm_single_input:on" - visible "*job_option ddm_generator:preprocessor" - help job_run_ddm_single_input - } - - roller { - position +23 = - size 21 4 - nvalues 2 - texts "MULTIPLE POST FILES" - "SINGLE POST FILE" - roller "job_option ddm_single_post" - commands "*job_option ddm_single_post:off" - "*job_option ddm_single_post:on" - help job_run_ddm_single_post - } - } - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_fea_solver_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - help job_param - } - - text { - position +10 = - size 4 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 0 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - button { - position +18 = - size 12 4 - text "ADV. SETTINGS" - popmenu job_ddm_fea_solver_pm - } -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_ddm_fea_solver_pm { - - text "JOB PARALLELIZATION" - - group { - units 32 120 - - - label { - position 0 5 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - frame { - - position 0 +9 - size 32 76 - text "ADVANCED DECOMPOSITION IN MARC" - border_width 1 - border_color black - - group { - - label { - position 1 4 - size 16 4 - text "# DOMAINS" - help job_param - } - - text { - position +16 = - size 14 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 1 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 23 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - frame { - position 1 +5 - size 30 20 - group job_ddm_direction_gr - visible "or(*job_option ddm_method:vector, \ - *job_option ddm_method:radial, \ - *job_option ddm_method:angular)" - } - - toggle { - position 1 +21 - size 30 4 - text "DOMAIN ISLAND REMOVAL" - toggle "*job_option ddm_island_removal:on" - true_command "*job_option ddm_island_removal:on" - false_command "*job_option ddm_island_removal:off" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "GRAPH" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "COARSE" - "FINE" - help ddm_decomp_coarse_graph - rollers "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - commands "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "QUADRATIC ELEMENTS" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "GENUINE" - "LINEARIZED" - help job_run_ddm_decomp_linearized - rollers "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - commands "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - } - - label { - position 1 +5 - size 15 4 - text "ELEMENT WEIGHT FACTOR" - help job_param - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_elem_weight_factor" - command "*job_param ddm_elem_weight_factor" - help job_run_ddm_decomp_element_weight_factor - } - - toggle { - position 1 +5 - size 30 4 - text "DETECT CONTACT" - toggle "*job_option ddm_detect_contact:on" - true_command "*job_option ddm_detect_contact:on" - false_command "*job_option ddm_detect_contact:off" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - help job_run_ddm_decomp_detect_contact - } - - label { - position = +5 - size 15 4 - text "CONTACT TOLERANCE" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - command "*set_ddm_contact_tolerance" - display "job_param_value_ddm_contact_tolerance" - command "*job_param ddm_contact_tolerance" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_tolerance - } - - label { - position -15 +4 - size 15 4 - text "CONTACT CONSTR FACTOR" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_contact_constr_factor" - command "*job_param ddm_contact_constr_factor" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_constraint_factor - } - } - } - - popdown { - position 0 +77 - size 32 8 - text "OK" - } - } - mode permanent -} # job_ddm_fea_solver_pm - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_direction_gr { - - button { - position 0 0 - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "*job_option ddm_method:vector" - } - - button { - position = = - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "not(*job_option ddm_method:vector)" - } - - button { - position +15 = - size 15 4 - text "FROM / TO" - command "*job_vector_from_to ddm_sort_direction_x" - } - - text { - position -15 +4 - size 10 4 - command "*job_param ddm_sort_direction_x" - display "job_param_value_ddm_sort_direction_x" - help ddm_job_decomp_user_direction_x - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_y" - display "job_param_value_ddm_sort_direction_y" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_z" - display "job_param_value_ddm_sort_direction_z" - } - - frame { - position 0 +4 - size 30 8 - group job_ddm_sort_point_gr - visible "not(*job_option ddm_method:vector)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_sort_point_gr { - - label { - position 0 0 - size 14 4 - border_width 1 - border_color black - text "POINT ON AXIS" - } - - roller { - position +14 = - size 10 4 - nvalues 2 - texts "DEFAULT" - "USER" - roller "job_option ddm_sort_point" - commands "*job_option ddm_sort_point:default" - "*job_option ddm_sort_point:user" - } - - button { - position +10 = - size 6 4 - text "SET" - command "*job_position ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position 0 +4 - size 10 4 - command "*job_param ddm_sort_point_x" - display "job_param_value_ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_y" - display "job_param_value_ddm_sort_point_y" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_z" - display "job_param_value_ddm_sort_point_z" - visible "*job_option ddm_sort_point:user" - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_preprocessor_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - border_width 1 - border_color black - } - - integer { - position +10 = - size 4 4 - display valid_domains - } - - button { - position 0 +4 - size 30 4 - text "USER DOMAINS" - popmenu domains_pm - help job_run_ddm_user_domains - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_assem_recov_gr { - - toggle { - position 1 +4 - size 30 4 - text "MULTIPLE THREADS" - true_command "*job_option assem_recov_multi_threading:on" - false_command "*job_option assem_recov_multi_threading:off" - toggle "*job_option assem_recov_multi_threading:on" - } - - label { - position = +4 - size 12 4 - text "# THREADS" - visible "*job_option assem_recov_multi_threading:on" - } - - text { - position +12 = - size 4 4 - display "job_param_value_assem_recov_nthreads" - command "*job_param assem_recov_nthreads" - visible "*job_option assem_recov_multi_threading:on" - } - - label { - position +4 = - size 10 4 - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - } - - display { - position +12 = - size 4 4 - display "job_assem_recov_nthreads_dom" - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - } - spacer{ - stretch 2 - } - -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_matrix_solver_gr { - layout vbox - frame { - position 1 0 - size 36 31 - group { - layout hbox - label { - position 3 4 - size 12 4 - text "SOLUTION" - border_width 1 - border_color black - } - oneonly { - position +12 = - size 12 4 - text "SYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_off" - command "*job_option solver_nonsym:off" - } - oneonly { - position +12 = - size 12 4 - text "NONSYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_on" - command "*job_option solver_nonsym:on" - } - spacer { - stretch 1 - } - } - } - - frame { - position 1 +5 - size 42 23 - group matrix_solver_gr - help job_param_solver - } - - frame { - position +1 = - size 42 4 - group job_run_solver_ddm_opts_gr - visible "*job_option parallel:on" - } - - frame { - position 1 +23 - size 42 8 - group job_solver_multi_procs_gr - visible solver_allows_multi_procs - } - - frame { - position = = - size 42 8 - group job_solver_multi_threads_gr - visible solver_allows_multi_threads - } - - frame { - position 1 +9 - size 42 8 - group job_solver_gpu_gr - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } - -} - - -#-------------------------------------------------------------------------------------------------- -group job_run_solver_ddm_opts_gr { - - button { - position 0 0 - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options -# see also job_common.ms! - visible "not(or(job_solver_it_sparse, \ - job_solver_it_ext, \ - job_solver_mixed_direct_iterative, \ - job_solver_pardiso,\ - job_solver_mumps))" - } - button { - position = = - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options_mumps - visible "job_solver_mumps" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_gr { - frame { - position 0 0 - size 42 8 - group job_solver_multi_procs_parallel_off_gr - visible "*job_option parallel:off" - } - - frame { - position = = - size 42 8 - group job_solver_multi_procs_parallel_on_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - true_command "*job_option nsolver_procs_serial:on" - false_command "*job_option nsolver_procs_serial:off" - toggle "*job_option nsolver_procs_serial:on" - help job_run_multithreading - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - visible "*job_option nsolver_procs_serial:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - visible "*job_option nsolver_procs_serial:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - border_width 1 - border_color black - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - help job_run_multithreading - rollers "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_nsolver_procs_ddm_automatic_gr - visible "*job_option nsolver_procs_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_nsolver_procs_ddm_user_gr - visible "*job_option nsolver_procs_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - } -} - -group job_solver_multi_threads_gr { - layout vbox - spacing 0 - - frame { - size 46 8 - group job_solver_multi_threads_it_sparse_parallel_off_gr - visible "and(job_solver_it_sparse,*job_option parallel:off)" - } - - frame { - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_off_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:off)" - } - - frame { - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_on_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:on)" - } - - frame { - size 46 8 - group job_solver_multi_threads_pardiso_parallel_off_gr - visible "and(job_solver_pardiso,*job_option parallel:off)" - } - - frame { - size 46 8 - group job_solver_multi_threads_pardiso_parallel_on_gr - visible "and(job_solver_pardiso,*job_option parallel:on)" - } - - frame { - size 46 8 - group job_solver_multi_threads_it_ext_off_gr - visible "and(job_solver_it_ext,*job_option parallel:off)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_it_sparse_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option it_sparse_multi_threading:on" - true_command "*job_option it_sparse_multi_threading:on" - false_command "*job_option it_sparse_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option it_sparse_multi_threading:on" - help job_run_multithreading - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option it_sparse_multi_threading:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option mfront_sparse_multi_threading:on" - true_command "*job_option mfront_sparse_multi_threading:on" - false_command "*job_option mfront_sparse_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option mfront_sparse_multi_threading:on" - help job_run_multithreading - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option mfront_sparse_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +30 0 - size 12 4 - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - help job_run_multithreading - } - - display { - position +12 0 - size 4 4 - display "job_mfront_sparse_nthreads_dom" - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - } - - label { - position 0 +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - help job_run_multithreading - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_automatic_gr - visible "*job_option mfront_sparse_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_user_gr - visible "*job_option mfront_sparse_multi_threading_ddm:user" - } -} -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_run_multithreading - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - - - -#-------------------------------------------------------------------------------------------------- -group job_solver_gpu_gr { - - toggle { - position 0 0 - size 30 4 - text "USE \{GPU(s)}" - toggle "*job_option solver_use_gpu:on" - true_command "*job_option solver_use_gpu:on" - false_command "*job_option solver_use_gpu:off" - help job_solver_gpu - } - frame{ - position 0 +4 - size 28 4 - group{ - layout hbox - - label { - position 0 0 - size 16 4 - text "\{GPU} SELECTION" - border_width 1 - border_color black - visible "*job_option solver_use_gpu:on" - } - - roller { - position +16 = - size 12 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - rollers "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - visible "*job_option solver_use_gpu:on" - help job_solver_gpu - } - - text { - position +12 = - size 12 4 - display job_solver_gpus - command "*clear_job_solver_gpus *job_solver_gpus" - visible "and(*job_option solver_use_gpu:on,*job_option solver_gpus:user)" - } - spacer { - stretch 1 - } - } - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option pardiso_multi_threading:on" - true_command "*job_option pardiso_multi_threading:on" - false_command "*job_option pardiso_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option pardiso_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option pardiso_multi_threading:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position = +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_pardiso_multi_threads_ddm_automatic_gr - visible "*job_option pardiso_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_pardiso_multi_threads_ddm_user_gr - visible "*job_option pardiso_multi_threading_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_it_ext_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option it_ext_multi_threading:on" - true_command "*job_option it_ext_multi_threading:on" - false_command "*job_option it_ext_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option it_ext_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option it_ext_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_gr { - - frame{ - position 0 +4 - size 40 4 - group{ - layout hbox - label{ - position 0 0 - size 8 4 - text "SETUP" - help job_run_ddm_setup - } - oneonly { - position +12 = - size 12 4 - text "SINGLE MACHINE" - oneonly "*job_option parallel_setup:single" - command "*job_option parallel_setup:single" - help job_run_ddm_setup - } - oneonly { - position +8 = - size 12 4 - text "NETWORK" - oneonly "*job_option parallel_setup:network" - command "*job_option parallel_setup:network" - help job_run_ddm_setup - } - - spacer { - stretch 1 - } - } - } - - - frame { - position +1 +5 - size 40 16 - group job_parallel_env_network_gr - visible "*job_option parallel_setup:network" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_gr { - - button { - position 0 0 - size 28 4 - text "HOST FILE" - browser host_file_browser - settext $host_file_browser_label "SELECT HOST FILE" - set $host_file_browser_command "*job_host_file" - help job_host_file - } - - button { - position +28 = - size 8 4 - text "EDIT" - command "*job_edit_host_file" - help job_edit_host_file - visible job_host_file - } - - button { - position +8 = - size 8 4 - text "CLEAR" - command "*job_clear_host_file" - help job_clear_host_file - visible job_host_file - } - - display { - position 0 +4 - size 44 4 - display job_host_file - } - - frame { - position 0 +5 - size 44 9 - group job_parallel_env_network_ddm_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_ddm_gr { - - toggle { - position 0 0 - size 22 4 - text "COPY INPUT FILE" - toggle "*job_option copy_input_file:on" - true_command "*job_option copy_input_file:on" - false_command "*job_option copy_input_file:off" - help job_host_copy_inputfile - } - - toggle { - position +23 = - size 21 4 - text "COPY POST FILE" - toggle "*job_option copy_post_file:on" - true_command "*job_option copy_post_file:on" - false_command "*job_option copy_post_file:off" - help job_host_copy_inputfile - } - - label { - position 0 +5 - size 10 4 - text "HOSTS" - border_width 1 - border_color black - visible job_usersub_file - } - - roller { - position +10 = - size 18 4 - nvalues 2 - texts "COMPATIBLE" - "INCOMPATIBLE" - roller "job_option network_hosts" - commands "*job_option network_hosts:compatible" - "*job_option network_hosts:incompatible" - help job_host_comp - visible job_usersub_file - } -} - - -#endif diff --git a/installation/mods_MarcMentat/2019/Marc_tools/comp_damask_hmp b/installation/mods_MarcMentat/2019/Marc_tools/comp_damask_hmp deleted file mode 100644 index 2e6f44b77..000000000 --- a/installation/mods_MarcMentat/2019/Marc_tools/comp_damask_hmp +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -usernoext=$user -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - -# add BLAS options for linking - BLAS="%BLAS%" - -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user on host `hostname`" -echo "program: $program" - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$usernoext.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $BLAS \ - $SYSLIBS || \ - { - echo "$0: link failed for $usernoext.o on host `hostname`" - exit 1 - } - /bin/rm $userobj - /bin/rm $DIRJOB/*.mod - /bin/rm $DIRJOB/*.smod diff --git a/installation/mods_MarcMentat/2019/Marc_tools/comp_damask_lmp b/installation/mods_MarcMentat/2019/Marc_tools/comp_damask_lmp deleted file mode 100644 index d908d68ed..000000000 --- a/installation/mods_MarcMentat/2019/Marc_tools/comp_damask_lmp +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -usernoext=$user -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - -# add BLAS options for linking - BLAS="%BLAS%" - -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user on host `hostname`" -echo "program: $program" - $DFORTRANLOWMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$usernoext.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $BLAS \ - $SYSLIBS || \ - { - echo "$0: link failed for $usernoext.o on host `hostname`" - exit 1 - } - /bin/rm $userobj - /bin/rm $DIRJOB/*.mod - /bin/rm $DIRJOB/*.smod diff --git a/installation/mods_MarcMentat/2019/Marc_tools/comp_damask_mp b/installation/mods_MarcMentat/2019/Marc_tools/comp_damask_mp deleted file mode 100644 index b31d84d48..000000000 --- a/installation/mods_MarcMentat/2019/Marc_tools/comp_damask_mp +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -usernoext=$user -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` -usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - -# add BLAS options for linking - BLAS="%BLAS%" - -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user on host `hostname`" -echo "program: $program" - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$usernoext.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $BLAS \ - $SYSLIBS || \ - { - echo "$0: link failed for $usernoext.o on host `hostname`" - exit 1 - } - /bin/rm $userobj - /bin/rm $DIRJOB/*.mod - /bin/rm $DIRJOB/*.smod diff --git a/installation/mods_MarcMentat/2019/Marc_tools/comp_user.original b/installation/mods_MarcMentat/2019/Marc_tools/comp_user.original deleted file mode 100644 index 8679bb041..000000000 --- a/installation/mods_MarcMentat/2019/Marc_tools/comp_user.original +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/ksh -# 1st arg: $DIR -# 2nd arg: $DIRJOB -# 3rd arg: $user -# 4th arg: $program -DIR=$1 -user=$3 -program=$4 -. $DIR/tools/include -DIRJOB=$2 -cd $DIRJOB -echo "Compiling and linking user subroutine $user.f on host `hostname`" -echo "program: $program" - $FORTRAN $user.f || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - userobj=$user.o - - - $LOAD ${program} $DIR/lib/main.o\ - $DIR/lib/blkdta.o $DIR/lib/comm?.o \ - ${userobj-} \ - $DIR/lib/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ../lib/mdsrc.a \ - ../lib/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $SYSLIBS || \ - { - echo "$0: link failed for $user.o on host `hostname`" - exit 1 - } - /bin/rm $userobj diff --git a/installation/mods_MarcMentat/2019/Marc_tools/include_linux64 b/installation/mods_MarcMentat/2019/Marc_tools/include_linux64 deleted file mode 100644 index 2bc9acc2f..000000000 --- a/installation/mods_MarcMentat/2019/Marc_tools/include_linux64 +++ /dev/null @@ -1,816 +0,0 @@ -# -# General definitions for the Marc 2019 version -# -# EM64T -# -# Linux RedHat 7.1, 7.3 / SuSE 11 SP4, 12 SP1 -# -# 64 bit MPI version -# -# Intel(R) Fortran Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.5.239 Build 20170817 -# -# Intel(R) C Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.5.239 Build 20170817 -# -# To check the O/S level, type: -# uname -a -# -# Distributed parallel MPI libraries: -# 1) HP MPI 2.3 -# To check the mpi version, type: -# mpirun -version -# 2) Intel MPI 2017.1 -# To check the mpi version, type: -# mpiexec.hydra -version -# -# To check the Compiler level, type using the compiler -# installation path: -# ifort -V -# icc -V -# -# REMARKS : This file contains the definitions of variables used during -# compilation loading and use of the MARC programmes . The -# current machine type is identified by means of the variable -# MACHINE , defined below. -# -# -# MPI_ROOT: root directory in which mpi shared libraries, etc. are located -# DIRJOB : directory in which spawned jobs should look for Marc input -# MPI_ARCH: system architecture -# MPI_EPATH: path where executable resides -# -REVISION="VERSION, BUILD" -HOSTNAME=`hostname` - -# find available memory in Mbyte on the machine -# can be set explicitly -MEMLIMIT=`free -m | awk '/Mem:/ {print $2}'` - -# set _OEM_NASTRAN to 1 for MD Nastran build -# override _OEM_NASTRAN setting with MARC_MD_NASTRAN environment variable -_OEM_NASTRAN="${MARC_MD_NASTRAN:-0}" - -# uncomment the following line for an autoforge build -#AUTOFORGE=1 -AUTOFORGE=0 -export AUTOFORGE - -# integer size -if test "$MARC_INTEGER_SIZE" = "" ; then - INTEGER_PATH= -else - INTEGER_PATH=/$MARC_INTEGER_SIZE -fi - -FCOMP=ifort -INTELPATH="/opt/intel/compilers_and_libraries_2017/linux" - -# find the root directory of the compiler installation: -# - if ifort is found in $PATH, then the root directory is derived -# from the path to ifort -# - if ifort is not found in $PATH, the root directory is assumed -# to be $INTELPATH and the directory in which ifort is found is -# added to $PATH -FCOMPPATH=`which "$FCOMP" 2>/dev/null` -if test -n "$FCOMPPATH"; then - # derive the root directory from $FCOMPPATH - FCOMPROOT="${FCOMPPATH%/bin/intel64/$FCOMP}" - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT="${FCOMPPATH%/bin/$FCOMP}" - fi - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT= - fi -elif test -d "$INTELPATH"; then - # check for compiler in $INTELPATH - if test -d "$INTELPATH/bin/intel64" -a \ - -x "$INTELPATH/bin/intel64/$FCOMP" ; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin/intel64:$PATH" - elif test -d "$INTELPATH/bin" -a \ - -x "$INTELPATH/bin/$FCOMP"; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin:$PATH" - else - FCOMPROOT= - fi -else - FCOMPROOT= -fi - -# DAMASK uses the HDF5 compiler wrapper around the Intel compiler -H5FC="$(h5fc -shlib -show)" -HDF5_LIB=${H5FC//ifort/} -FCOMP="$H5FC -DDAMASK_HDF5" - -# AEM -if test "$MARCDLLOUTDIR" = ""; then - DLLOUTDIR="$MARC_LIB" -else - DLLOUTDIR="$MARCDLLOUTDIR" -fi - -# settings for MKL -if test "$IMKLDIR" = ""; then - MARC_MKL="$FCOMPROOT/mkl/lib/intel64" -else - MARC_MKL=$IMKLDIR/lib/intel64 -fi - -# -# settings for Metis -# -METIS="-I$METIS_SOURCE/include" -METISLIBS="$METISLIB_DIR/libmarcddm.a $METISLIB_DIR/libmarcmetis.a " - -# -# settings for MPI -# -# RCP and RSH are used for parallel network runs -# replace with similar commands like rsh if needed -RCP=/usr/bin/scp -RSH=/usr/bin/ssh -# - - -MPI_DEFAULT=intelmpi -MPI_OTHER=hpmpi - -MPITYPE=$MPI_DEFAULT - -if test $AUTOFORGE -then - if test $AUTOFORGE = 1 - then - MPITYPE=none - fi -fi - - -# overrule MPITYPE setting with environmental variable MARC_MPITYPE -if test $MARC_MPITYPE -then - MPITYPE=$MARC_MPITYPE -fi - -# always set MPITYPE to none for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - MPITYPE=none -fi - -# Edit following lines to build with GPGPU version of BCS Solver for -# NVIDIA platforms -#BCSGPUSOLVER=NONE -BCSGPUSOLVER=BCSGPU - -# Edit following lines to set the openssl library -if test "$OPENSSL" != "NONE" -then - OPENSSL_LIB="$MARC_LIB/libcrypto.a" -fi -OPENSSL_INCLUDE=-I"$MARC_OPENSSL/include/" - -MARCHDF=HDF -#MARCHDF=NONE -if test "$MARCHDF" = "HDF"; then - HDF_INCLUDE="-I$MARC_HDF/include" - HDF_LIBS="$MARC_LIB/libhdf5_fortran.so.100 $MARC_LIB/libhdf5.so.101" -fi - -# activate contact component build if flagged -AEM_DLL=0 -if test "$AEM_BUILD" = "ON" ; then - AEM_DLL=1 - LINK_MARC_DLL="-shared -fPIC" - EXT_DLL="so" - MPITYPE=none - MPI_OTHER= - BCSGPUSOLVER=NONE - MUMPSSOLVER=NONE - CASISOLVER=NONE -fi - -SOLVERFLAGS= -if test "$BCSGPUSOLVER" = BCSGPU -then - SOLVERFLAGS="$SOLVERFLAGS -DBCSGPU -DCUDA" - BCS_DIR=bcsgpusolver -else - BCS_DIR=bcssolver -fi -# -# settings for MPI -# -DDM= -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - FCOMPMPI=mpif90 - export MPI_ROOT=$MARC_HPMPI - export MPI_REMSH=$RSH - export MPI_F77=$FCOMP - ARCHITECTURE=linux_amd64 - DDM="-I$MPI_ROOT/include/64 -DDDM -DHPMPI" - MPI_CLEAN= - export MPI_EPATH=$MARC_BIN - export LD_LIBRARY_PATH=$MPI_ROOT/lib/$ARCHITECTURE:$MARC_LIB:$MARC_LIB_SHARED:$LD_LIBRARY_PATH - export MPIHPSPECIAL="-e MPI_FLAGS=E,T,y1" -# Below line is moved in run_marc file -# export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - export MPIHPSPECIAL="$MPIHPSPECIAL -e BINDIR=$MARC_BIN" - if test -n "$MSC_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e MSC_LICENSE_FILE=$MSC_LICENSE_FILE" - fi - if test -n "$LM_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LM_LICENSE_FILE=$LM_LICENSE_FILE" - fi - export MPIHPSPECIAL="$MPIHPSPECIAL -e MPI_LIC_CHECKER=$MPI_ROOT/bin/licensing/amd64_s8/lichk.x" - RUN_JOB2="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -f " - RUN_JOB1="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -w $MPIHPSPECIAL -np " - RUN_JOB0= - fi - if test $MPITYPE = intelmpi - then - INTELMPI_VERSION=HYDRA - FCOMPMPI=mpiifort - MPI_ROOT=$MARC_INTELMPI - DDM="-I${MPI_ROOT}/include -DDDM" - PATH=$MPI_ROOT/bin:$PATH - export PATH - LD_LIBRARY_PATH=$MPI_ROOT/lib:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - if test $INTELMPI_VERSION = HYDRA - then - RUN_JOB1="${MPI_ROOT}/bin/mpiexec.hydra -genvall -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec.hydra -genvall" - else - RUN_JOB1="${MPI_ROOT}/bin/mpiexec -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec -configfile " - fi - RUN_JOB0= - MPI_CLEAN= - MPI_EPATH=$MARC_BIN - MPIR_HOME=$MPI_ROOT - MPICH_F77=$FCOMP - MPICH_F77LINKER=$FCOMP - export MPI_ROOT MPI_EPATH MPIR_HOME MPICH_F77 MPICH_F77LINKER - I_MPI_PIN_DOMAIN=node - export I_MPI_PIN_DOMAIN - fi -else - MPI_ROOT=$MARC_DUMMYMPI - export MPI_ROOT=$MARC_DUMMYMPI - DDM="-I$MPI_ROOT/include" -fi - -# -# variables for the "maintain" script -# - -MACHINENAME=LINUX -MACHINE64BIT=yes -MACHINE=Linux_EM64T -DEV=/dev/tape -GETLOG="whoami" -CLEAR="clear" -MY_UNAME=`uname -a` - -# Edit following 2 lines to build with VKI Solver -#VKISOLVER=VKI -VKISOLVER=NONE - -# Edit following 2 lines to build with CASI Solver -CASISOLVER=CASI -if test "$MARC_CASISOLVER" = "NONE" ; then - CASISOLVER=NONE -fi -#CASISOLVER=NONE - -# Edit following 2 lines to build with MF2 Solver -MF2SOLVER=NONE -#MF2SOLVER=SERIAL -#MF2SOLVER=MF2PARALLEL - -# Edit following lines to build with Intel(c) Multithreaded solver (PARDISO) -#INTELSOLVER=NONE -INTELSOLVER=PARDISO - -# Edit following lines to build with MUMPS -if test "$MARC_INTEGER_SIZE" = "i4" ; then - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -else - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -fi - -# Edit following 2 lines to build MARC dynamic shared library -MARC_DLL=MARC_DLL -MARC_DLL=NONE - -# always set VKISOLVER, CASISOLVER, BCSGPUSOLVER, and MARC_DLL to NONE for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE - MARC_DLL=NONE -fi -if test "$AEM_DLL" -eq 1 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE -fi - -# -# define Fortran and C compile syntax -# -if test "$VKISOLVER" = VKI -then - SOLVERFLAGS="$SOLVERFLAGS -DVKI" -fi - -if test "$CASISOLVER" = CASI -then - SOLVERFLAGS="$SOLVERFLAGS -DCASI" -fi - -if test "$MF2SOLVER" = MF2PARALLEL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2PARALLEL" -fi -if test "$MF2SOLVER" = MF2SERIAL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2SERIAL" -fi - -if test "$INTELSOLVER" = PARDISO -then - SOLVERFLAGS="$SOLVERFLAGS -DPARDISO" -fi - -if test "$MUMPSSOLVER" = MUMPS -then - SOLVERFLAGS="$SOLVERFLAGS -DMUMPS" -fi - - -if test "$MARC_DLL" = MARC_DLL -then - SOLVERFLAGS="$SOLVERFLAGS -DMARC_DLL" -fi - -LINK_OPT= -DEBUG_OPT= -C_DEBUG_OPT= - -#Uncomment following line to build Marc in debuggable mode -MARCDEBUG= -#MARCDEBUG="ON" - -if test "$MARCDEBUG" = "ON" -then - LINK_OPT="-debug -traceback" - DEBUG_OPT="-debug -traceback" - C_DEBUG_OPT="-debug -traceback" -fi - - -MARCCHECK= -#MARCCHECK="ON" -if test "$MARCCHECK" = "ON" -then - DEBUG_OPT="$DEBUG_OPT -fpe0 -fp-stack-check -check all -ftrapuv " - C_DEBUG_OPT="$C_DEBUG_OPT -fp-stack-check -check-uninit -Wformat -ftrapuv " -fi - -MARCCODECOV= -#MARCCODECOV="ON" - -MARCCODEPROF= -#MARCCODEPROF="ON" - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - I8FFLAGS= - I8DEFINES= - I8CDEFINES= -else - I8FFLAGS="-i8 -integer-size 64" - I8DEFINES="-DI64 -DINT=8" - I8CDEFINES="-U_DOUBLE -D_SINGLE" -fi - -MTHREAD=OPENMP -if test "$MARC_OPENMP" = "NONE" ; then - MTHREAD=NONE -fi -#MTHREAD=NONE -if test "$_OEM_NASTRAN" -ne 0 -then -MTHREAD=NONE -fi -if test "$AEM_DLL" -eq 1 -then - MTHREAD=NONE - CASISOLVER=NONE - VKISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - BCSGPUSOLVER=NONE - OPENSSL_LIB= - MARC_DLL=NONE - METISLIBS= -fi - -OMP_COMPAT=NO -OMP_COMPAT=YES -if test "$MTHREAD" = "NONE" -then -OMP_COMPAT=NO -fi - -CDEFINES= -FDEFINES= - -if test "$_OEM_NASTRAN" -ne 0 -then - CDEFINES="$CDEFINES -D_OEM_NASTRAN" - FDEFINES="$FDEFINES -D_OEM_NASTRAN" -fi - -FDEFINES="$FDEFINES -D_IMPLICITNONE" - -if test "$_OEM_NASTRAN" -eq 0 -then - FDEFINES="$FDEFINES -DMKL -DOPENMP" -fi - -if test "$OMP_COMPAT" = "YES" -then - FDEFINES="$FDEFINES -DOMP_COMPAT" -fi - -# -D_MSCMARC -FDEFINES="$FDEFINES -D_MSCMARC $DEBUG_OPT $MARC_SIMUFACT" -CDEFINES="$CDEFINES -D_MSCMARC $C_DEBUG_OPT $I8CDEFINES" - -if test "$AEM_DLL" -eq 1 -then - FDEFINES="$FDEFINES -D_AEMNL -DAAA" - CDEFINES="$CDEFINES -D_AEMNL -DAAA" -fi - -CINCL="-I$MARC_SOURCE/mdsrc -I$MARC_SOURCE/csource $METIS -I$LAPI_IMPORTS/common/include" -if test "$_OEM_NASTRAN" -ne 0 -then - CINCL="$CINCL -I../../include" -fi - -CC_OPT= -if test "$MTHREAD" = "OPENMP" -then - CC_OPT=" $CC_OPT -qopenmp" -fi - -CC="icc -c $CC_OPT -O1 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCLOW="icc -c $CC_OPT -O0 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCHIGH="icc -c $CC_OPT -O3 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - -if test "$MARCDEBUG" = "ON" -then - CC="icc -c $CC_OPT -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCLOW="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCHIGH="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -fi - -LOAD_CC="icc $CC_OPT -O1 -DLinux -DLINUX -DLinux_intel" -CCT="$CC" -CCTLOW="$CCLOW" -CCTHIGH="$CCHIGH" - -#PROFILE="-Mprof=func" -#PROFILE="-Mprof=lines" -#PROFILE="-Mprof=func,mpi" -PROFILE= -#PROFILE="-init=snan,arrays -CB -traceback -fpe0 -fp-stack-check -check all -check uninit -ftrapuv" -if test "$MARCCODECOV" = "ON" -then -PROFILE="-prof-gen=srcpos" -fi -if test "$MARCCODEPROF" = "ON" -then -PROFILE=" $PROFILE -pg" -fi - -FORT_OPT="-c -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr -mp1 -WB -fp-model source" -if test "$MTHREAD" = "OPENMP" -then - FORT_OPT=" $FORT_OPT -qopenmp" - if test "$OMP_COMPAT" = "YES" - then - FORT_OPT=" $FORT_OPT -qopenmp-threadprivate=compat" - fi -else -# FORT_OPT=" $FORT_OPT -auto " - FORT_OPT=" $FORT_OPT -save -zero" -fi -if test "$MARCHDF" = "HDF"; then - FORT_OPT="$FORT_OPT -DMARCHDF=$MARCHDF" -fi - -FORTLOW="$FCOMP $FORT_OPT $PROFILE -O0 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTRAN="$FCOMP $FORT_OPT $PROFILE -O1 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTNA="$FCOMP $FORT_OPT -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -# for compiling free form f90 files. high opt, integer(4) -FORTF90="$FCOMP -c -O3" - -# determine DAMASK version -if test -n "$DAMASK_USER"; then - DAMASKROOT=`dirname $DAMASK_USER`/.. - read DAMASKVERSION < $DAMASKROOT/VERSION - DAMASKVERSION="'"$DAMASKVERSION"'" -else - DAMASKVERSION="'N/A'" -fi - - -# DAMASK compiler calls: additional flags are in line 2 OpenMP flags in line 3 -DFORTLOWMP="$FCOMP -c -O0 -qno-offload -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2019 -DDAMASKVERSION=$DAMASKVERSION \ - -qopenmp -qopenmp-threadprivate=compat\ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -DFORTRANMP="$FCOMP -c -O1 -qno-offload -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2019 -DDAMASKVERSION=$DAMASKVERSION \ - -qopenmp -qopenmp-threadprivate=compat\ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -DFORTHIGHMP="$FCOMP -c -O3 -qno-offload -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2019 -DDAMASKVERSION=$DAMASKVERSION \ - -qopenmp -qopenmp-threadprivate=compat\ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - -if test "$MARCDEBUG" = "ON" -then - FORTLOW="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTRAN="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTNA="$FCOMP $FORT_OPT -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -fi - - -FORTLOWT="$FORTLOW" -FORTRANT="$FORTRAN" -FORTHIGHT="$FORTHIGH" - -FORTRANMNF="$FCOMP -c $FDEFINES " -CCMNF="icc -c -O1 -DLinux -DLINUX -DLinux_intel -Dport2egcs -I$MARC_SOURCE/marctoadams/mnf/include -D_LARGEFILE64_SOURCE" - -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - LOAD="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - LOADT="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - fi -# Uncomment the following lines to turn on the tracer and commnet out the next 5 lines -# if test $MPITYPE = intelmpi -# then -# INCLUDEMPI="-I$MPI_ROOT/include -I$VT_ROOT/include" -# LOAD="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# LOADT="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# fi - if test $MPITYPE = intelmpi - then - LOAD="ifort $PROFILE $LINK_OPT -o " - LOADT="ifort $PROFILE $LINK_OPT -o " - fi -else - LOAD="$FCOMP $LINK_OPT -o " - LOADT="$FCOMP $LINK_OPT -o " -fi - -if test "$MARC_DLL" = MARC_DLL -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide -lpthread" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - -if test "$AEM_DLL" -eq 1 -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - - -XLIBS="-L/usr/X11/lib -lX11 " - -# -# define archive and ranlib syntax -# - -ARC="ar rvl" -ARD="ar dvl" -ARX="ar xl" -RAN="" - -# -# choose which libraries you want to use ( e.g. blas ) -# - -if test "$VKISOLVER" = VKI -then - VKISOLVERLIBS="$MARC_LIB/vkisolver.a" -else - VKISOLVERLIBS= -fi - -if test "$CASISOLVER" = CASI -then - CASISOLVERLIBS="$CASILIB_DIR/libmarccasi.a $CASILIB_DIR/libcasi.a" -else - CASISOLVERLIBS= -fi - -MF2SOLVERLIBS= -if test "$MF2SOLVER" = MF2PARALLEL -then - MF2SOLVERLIBS="$MARC_LIB/mf2parallel/libseq.a \ - $MARC_LIB/mf2parallel/libsym.a \ - $MARC_LIB/mf2parallel/libmet.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libnum.a \ - $MARC_LIB/mf2parallel/libutl.a \ - $MARC_LIB/mf2parallel/libr8.a \ - $MARC_LIB/mf2parallel/libz.a " -fi - -if test "$MUMPSSOLVER" = MUMPS -then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - if test $MPITYPE = none - then - MUMPSSOLVERLIBS2= - echo hello > /dev/null - fi - if test $MPITYPE = intelmpi - then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_intelmpi.a" - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a " - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a " - fi - fi - if test $MPITYPE = hpmpi - then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_hpmpi.a" - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a" - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a" - fi - fi -else - MUMPSSOLVERLIBS= - MUMPSSOLVERLIBS2= -fi - -if test "$BCSGPUSOLVER" = BCSGPU -then - BCSSOLVERLIBS="${BCSLIB_DIR}/bcsgpulib.a " - MARCCUDALIBS1="-L${BCSLIB_DIR}/cuda_dummy -lmarccuda " - MARCCUDALIBS2="-L${BCSLIB_DIR}/cuda -lmarccuda " - MARCCUDALIBS=$MARCCUDALIBS1 -else - BCSSOLVERLIBS="${MARC_LIB}/bcslib.a " -fi -if test "$AEM_DLL" -eq 1 -then - BCSSOLVERLIBS= -fi - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - MKLLIB="$MARC_MKL/libmkl_scalapack_lp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_lp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MARC_MKL/libmkl_blacs_intelmpi_lp64.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -else - MKLLIB="$MARC_MKL/libmkl_scalapack_ilp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_ilp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -fi - -SECLIBS="-L$MARC_LIB -llapi" - -SOLVERLIBS="${BCSSOLVERLIBS} ${VKISOLVERLIBS} ${CASISOLVERLIBS} ${MF2SOLVERLIBS} \ - $MKLLIB -L$MARC_MKL -liomp5 \ - $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/kdtree2.a $HDF5_LIB" - -SOLVERLIBS_DLL=${SOLVERLIBS} -if test "$AEM_DLL" -eq 1 -then -SOLVERLIBS_DLL="$MKLLIB -L$MARC_MKL -liomp5 $MARC_LIB/blas_src.a" -fi -MRCLIBS="$MARC_LIB/clib.a ${CASISOLVERLIBS}" -MRCLIBSPAR="$MARC_LIB/clib.a" -STUBS="$MARC_LIB/stubs.a " -MNFLIBS="$MARC_LIB/libmnf.a" -MDUSER="$MARC_LIB/md_user.a" -if test "X$MARC_SIMUFACT" = "X-DSIMUFACT" || test -f "$MARC_LIB/libMBA_Grain.so" -then - SFLIB="-L$SFMATDIR -lMBA_Grain $SFMATDIR/sfclib.a " -else - SFLIB=" " -fi - -OPENMP="-qopenmp" - -if test "$AEM_DLL" -eq 1 -then - LOAD_DLL=$LOAD - OPENMP= - LIBMNF= - OPENSSL=NONE -fi - -SYSLIBS=" $OPENMP -lpthread -cxxlib" - -# Uncomment the following lines to turn on the trace and comment out the next 4 lines -# if test $MPITYPE = intelmpi -# then -# SYSLIBS="-L${VT_ROOT}/lib -lVT -ldwarf -lelf -lm -lpthread \ -# -L${MPI_ROOT}/lib64 -lmpi -lmpiif -lmpigi -lrt" -# fi -if test $MPITYPE = intelmpi -then - SYSLIBS="-L${MPI_ROOT}/lib -lmpi_mt -lmpifort -lrt $OPENMP -threads -lpthread -cxxlib" -fi - - -SYSLIBSPAR=" " - -MARC_DLL_CODES="runmarc.f" - - -BLAS_SRC="dzero.f icopy.f izero.f" -if test "$_OEM_NASTRAN" -ne 0 -then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - BLAS_SRC="$BLAS_SRC dsctr.f zsctr.f dzasum.f daxpyi.f zaxpyi.f dgthr.f zgthr.f" - else - BLAS_SRC="ALL" - fi -fi - -LOW_OPT_CODES="are163.f contro.f ndext.f omarc.f omarca.f omarcb.f omarcc.f \ - omars.f fixbc.f triang.f bet049.f norst3.f eldata.f \ - elec*.f elct*.f fmeig.f oada00.f ogeig.f updtrbe2.f cycrota.f \ - cordef.f ogpk.f ogtan.f eldam.f formrbe3.f \ - inertie.f em_sso072.f cn_fol3d_qpatch6.f cosim_begin.f" -if test "$MARC_INTEGER_SIZE" = "i8" ; then - LOW_OPT_CODES="$LOW_OPT_CODES bbcseg.f" -fi - -HIGH_OPT_CODES="dpsmsa1.f dpsmsa2.f dpsmsa3.f dpsmsa4.f dpsmsa5.f dpsmsa6.f \ - dpsmsa7.f dpsmsa8.f dpsmsa9.f dpsmsa10.f dpsmsa11.f dpsmsa12.f \ - dpsmsa13.f dpsmsa14.f dpsmsa15.f dpsmsa16.f dpsmsah.f tpsmsah.f cn_qsort4_11.f " - - - -MAXNUM=1000000 diff --git a/installation/mods_MarcMentat/2019/Marc_tools/include_linux64.original b/installation/mods_MarcMentat/2019/Marc_tools/include_linux64.original deleted file mode 100644 index 9a84e3361..000000000 --- a/installation/mods_MarcMentat/2019/Marc_tools/include_linux64.original +++ /dev/null @@ -1,786 +0,0 @@ -# -# General definitions for the Marc 2019 version -# -# EM64T -# -# Linux RedHat 7.1, 7.3 / SuSE 11 SP4, 12 SP1 -# -# 64 bit MPI version -# -# Intel(R) Fortran Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.5.239 Build 20170817 -# -# Intel(R) C Intel(R) 64 Compiler XE for applications -# running on Intel(R) 64, Version 17.0.5.239 Build 20170817 -# -# To check the O/S level, type: -# uname -a -# -# Distributed parallel MPI libraries: -# 1) HP MPI 2.3 -# To check the mpi version, type: -# mpirun -version -# 2) Intel MPI 2017.1 -# To check the mpi version, type: -# mpiexec.hydra -version -# -# To check the Compiler level, type using the compiler -# installation path: -# ifort -V -# icc -V -# -# REMARKS : This file contains the definitions of variables used during -# compilation loading and use of the MARC programmes . The -# current machine type is identified by means of the variable -# MACHINE , defined below. -# -# -# MPI_ROOT: root directory in which mpi shared libraries, etc. are located -# DIRJOB : directory in which spawned jobs should look for Marc input -# MPI_ARCH: system architecture -# MPI_EPATH: path where executable resides -# -REVISION="VERSION, BUILD" -HOSTNAME=`hostname` - -# find available memory in Mbyte on the machine -# can be set explicitly -MEMLIMIT=`free -m | awk '/Mem:/ {print $2}'` - -# set _OEM_NASTRAN to 1 for MD Nastran build -# override _OEM_NASTRAN setting with MARC_MD_NASTRAN environment variable -_OEM_NASTRAN="${MARC_MD_NASTRAN:-0}" - -# uncomment the following line for an autoforge build -#AUTOFORGE=1 -AUTOFORGE=0 -export AUTOFORGE - -# integer size -if test "$MARC_INTEGER_SIZE" = "" ; then - INTEGER_PATH= -else - INTEGER_PATH=/$MARC_INTEGER_SIZE -fi - -FCOMP=ifort -INTELPATH="/opt/intel/compilers_and_libraries_2017/linux" - -# find the root directory of the compiler installation: -# - if ifort is found in $PATH, then the root directory is derived -# from the path to ifort -# - if ifort is not found in $PATH, the root directory is assumed -# to be $INTELPATH and the directory in which ifort is found is -# added to $PATH -FCOMPPATH=`which "$FCOMP" 2>/dev/null` -if test -n "$FCOMPPATH"; then - # derive the root directory from $FCOMPPATH - FCOMPROOT="${FCOMPPATH%/bin/intel64/$FCOMP}" - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT="${FCOMPPATH%/bin/$FCOMP}" - fi - if test "$FCOMPROOT" = "$FCOMPPATH"; then - FCOMPROOT= - fi -elif test -d "$INTELPATH"; then - # check for compiler in $INTELPATH - if test -d "$INTELPATH/bin/intel64" -a \ - -x "$INTELPATH/bin/intel64/$FCOMP" ; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin/intel64:$PATH" - elif test -d "$INTELPATH/bin" -a \ - -x "$INTELPATH/bin/$FCOMP"; then - FCOMPROOT="$INTELPATH" - PATH="$INTELPATH/bin:$PATH" - else - FCOMPROOT= - fi -else - FCOMPROOT= -fi - -# AEM -if test "$MARCDLLOUTDIR" = ""; then - DLLOUTDIR="$MARC_LIB" -else - DLLOUTDIR="$MARCDLLOUTDIR" -fi - -# settings for MKL -if test "$IMKLDIR" = ""; then - MARC_MKL="$FCOMPROOT/mkl/lib/intel64" -else - MARC_MKL=$IMKLDIR/lib/intel64 -fi - -# -# settings for Metis -# -METIS="-I$METIS_SOURCE/include" -METISLIBS="$METISLIB_DIR/libmarcddm.a $METISLIB_DIR/libmarcmetis.a " - -# -# settings for MPI -# -# RCP and RSH are used for parallel network runs -# replace with similar commands like rsh if needed -RCP=/usr/bin/scp -RSH=/usr/bin/ssh -# - - -MPI_DEFAULT=intelmpi -MPI_OTHER=hpmpi - -MPITYPE=$MPI_DEFAULT - -if test $AUTOFORGE -then - if test $AUTOFORGE = 1 - then - MPITYPE=none - fi -fi - - -# overrule MPITYPE setting with environmental variable MARC_MPITYPE -if test $MARC_MPITYPE -then - MPITYPE=$MARC_MPITYPE -fi - -# always set MPITYPE to none for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - MPITYPE=none -fi - -# Edit following lines to build with GPGPU version of BCS Solver for -# NVIDIA platforms -#BCSGPUSOLVER=NONE -BCSGPUSOLVER=BCSGPU - -# Edit following lines to set the openssl library -if test "$OPENSSL" != "NONE" -then - OPENSSL_LIB="$MARC_LIB/libcrypto.a" -fi -OPENSSL_INCLUDE=-I"$MARC_OPENSSL/include/" - -MARCHDF=HDF -#MARCHDF=NONE -if test "$MARCHDF" = "HDF"; then - HDF_INCLUDE="-I$MARC_HDF/include" - HDF_LIBS="$MARC_LIB/libhdf5_fortran.so.100 $MARC_LIB/libhdf5.so.101" -fi - -# activate contact component build if flagged -AEM_DLL=0 -if test "$AEM_BUILD" = "ON" ; then - AEM_DLL=1 - LINK_MARC_DLL="-shared -fPIC" - EXT_DLL="so" - MPITYPE=none - MPI_OTHER= - BCSGPUSOLVER=NONE - MUMPSSOLVER=NONE - CASISOLVER=NONE -fi - -SOLVERFLAGS= -if test "$BCSGPUSOLVER" = BCSGPU -then - SOLVERFLAGS="$SOLVERFLAGS -DBCSGPU -DCUDA" - BCS_DIR=bcsgpusolver -else - BCS_DIR=bcssolver -fi -# -# settings for MPI -# -DDM= -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - FCOMPMPI=mpif90 - export MPI_ROOT=$MARC_HPMPI - export MPI_REMSH=$RSH - export MPI_F77=$FCOMP - ARCHITECTURE=linux_amd64 - DDM="-I$MPI_ROOT/include/64 -DDDM -DHPMPI" - MPI_CLEAN= - export MPI_EPATH=$MARC_BIN - export LD_LIBRARY_PATH=$MPI_ROOT/lib/$ARCHITECTURE:$MARC_LIB:$MARC_LIB_SHARED:$LD_LIBRARY_PATH - export MPIHPSPECIAL="-e MPI_FLAGS=E,T,y1" -# Below line is moved in run_marc file -# export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - export MPIHPSPECIAL="$MPIHPSPECIAL -e BINDIR=$MARC_BIN" - if test -n "$MSC_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e MSC_LICENSE_FILE=$MSC_LICENSE_FILE" - fi - if test -n "$LM_LICENSE_FILE" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LM_LICENSE_FILE=$LM_LICENSE_FILE" - fi - export MPIHPSPECIAL="$MPIHPSPECIAL -e MPI_LIC_CHECKER=$MPI_ROOT/bin/licensing/amd64_s8/lichk.x" - RUN_JOB2="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -f " - RUN_JOB1="$MPI_ROOT/bin/mpirun ${MPIRUNOPTIONS} -prot -w $MPIHPSPECIAL -np " - RUN_JOB0= - fi - if test $MPITYPE = intelmpi - then - INTELMPI_VERSION=HYDRA - FCOMPMPI=mpiifort - MPI_ROOT=$MARC_INTELMPI - DDM="-I${MPI_ROOT}/include -DDDM" - PATH=$MPI_ROOT/bin:$PATH - export PATH - LD_LIBRARY_PATH=$MPI_ROOT/lib:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - if test $INTELMPI_VERSION = HYDRA - then - RUN_JOB1="${MPI_ROOT}/bin/mpiexec.hydra -genvall -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec.hydra -genvall" - else - RUN_JOB1="${MPI_ROOT}/bin/mpiexec -n " - RUN_JOB2="${MPI_ROOT}/bin/mpiexec -configfile " - fi - RUN_JOB0= - MPI_CLEAN= - MPI_EPATH=$MARC_BIN - MPIR_HOME=$MPI_ROOT - MPICH_F77=$FCOMP - MPICH_F77LINKER=$FCOMP - export MPI_ROOT MPI_EPATH MPIR_HOME MPICH_F77 MPICH_F77LINKER - I_MPI_PIN_DOMAIN=node - export I_MPI_PIN_DOMAIN - fi -else - MPI_ROOT=$MARC_DUMMYMPI - export MPI_ROOT=$MARC_DUMMYMPI - DDM="-I$MPI_ROOT/include" -fi - -# -# variables for the "maintain" script -# - -MACHINENAME=LINUX -MACHINE64BIT=yes -MACHINE=Linux_EM64T -DEV=/dev/tape -GETLOG="whoami" -CLEAR="clear" -MY_UNAME=`uname -a` - -# Edit following 2 lines to build with VKI Solver -#VKISOLVER=VKI -VKISOLVER=NONE - -# Edit following 2 lines to build with CASI Solver -CASISOLVER=CASI -if test "$MARC_CASISOLVER" = "NONE" ; then - CASISOLVER=NONE -fi -#CASISOLVER=NONE - -# Edit following 2 lines to build with MF2 Solver -MF2SOLVER=NONE -#MF2SOLVER=SERIAL -#MF2SOLVER=MF2PARALLEL - -# Edit following lines to build with Intel(c) Multithreaded solver (PARDISO) -#INTELSOLVER=NONE -INTELSOLVER=PARDISO - -# Edit following lines to build with MUMPS -if test "$MARC_INTEGER_SIZE" = "i4" ; then - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -else - #MUMPSSOLVER=NONE - MUMPSSOLVER=MUMPS -fi - -# Edit following 2 lines to build MARC dynamic shared library -MARC_DLL=MARC_DLL -MARC_DLL=NONE - -# always set VKISOLVER, CASISOLVER, BCSGPUSOLVER, and MARC_DLL to NONE for MD Nastran -if test "$_OEM_NASTRAN" -ne 0 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE - MARC_DLL=NONE -fi -if test "$AEM_DLL" -eq 1 -then - VKISOLVER=NONE - CASISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - MUMPSSOLVER=NONE - BCSGPUSOLVER=NONE -fi - -# -# define Fortran and C compile syntax -# -if test "$VKISOLVER" = VKI -then - SOLVERFLAGS="$SOLVERFLAGS -DVKI" -fi - -if test "$CASISOLVER" = CASI -then - SOLVERFLAGS="$SOLVERFLAGS -DCASI" -fi - -if test "$MF2SOLVER" = MF2PARALLEL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2PARALLEL" -fi -if test "$MF2SOLVER" = MF2SERIAL -then - SOLVERFLAGS="$SOLVERFLAGS -DMF2SERIAL" -fi - -if test "$INTELSOLVER" = PARDISO -then - SOLVERFLAGS="$SOLVERFLAGS -DPARDISO" -fi - -if test "$MUMPSSOLVER" = MUMPS -then - SOLVERFLAGS="$SOLVERFLAGS -DMUMPS" -fi - - -if test "$MARC_DLL" = MARC_DLL -then - SOLVERFLAGS="$SOLVERFLAGS -DMARC_DLL" -fi - -LINK_OPT= -DEBUG_OPT= -C_DEBUG_OPT= - -#Uncomment following line to build Marc in debuggable mode -MARCDEBUG= -#MARCDEBUG="ON" - -if test "$MARCDEBUG" = "ON" -then - LINK_OPT="-debug -traceback" - DEBUG_OPT="-debug -traceback" - C_DEBUG_OPT="-debug -traceback" -fi - - -MARCCHECK= -#MARCCHECK="ON" -if test "$MARCCHECK" = "ON" -then - DEBUG_OPT="$DEBUG_OPT -fpe0 -fp-stack-check -check all -ftrapuv " - C_DEBUG_OPT="$C_DEBUG_OPT -fp-stack-check -check-uninit -Wformat -ftrapuv " -fi - -MARCCODECOV= -#MARCCODECOV="ON" - -MARCCODEPROF= -#MARCCODEPROF="ON" - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - I8FFLAGS= - I8DEFINES= - I8CDEFINES= -else - I8FFLAGS="-i8" - I8DEFINES="-DI64" - I8CDEFINES="-U_DOUBLE -D_SINGLE" -fi - -MTHREAD=OPENMP -if test "$MARC_OPENMP" = "NONE" ; then - MTHREAD=NONE -fi -#MTHREAD=NONE -if test "$_OEM_NASTRAN" -ne 0 -then -MTHREAD=NONE -fi -if test "$AEM_DLL" -eq 1 -then - MTHREAD=NONE - CASISOLVER=NONE - VKISOLVER=NONE - MF2SOLVER=NONE - INTELSOLVER=NONE - BCSGPUSOLVER=NONE - OPENSSL_LIB= - MARC_DLL=NONE - METISLIBS= -fi - -OMP_COMPAT=NO -OMP_COMPAT=YES -if test "$MTHREAD" = "NONE" -then -OMP_COMPAT=NO -fi - -CDEFINES= -FDEFINES= - -if test "$_OEM_NASTRAN" -ne 0 -then - CDEFINES="$CDEFINES -D_OEM_NASTRAN" - FDEFINES="$FDEFINES -D_OEM_NASTRAN" -fi - -FDEFINES="$FDEFINES -D_IMPLICITNONE" - -if test "$_OEM_NASTRAN" -eq 0 -then - FDEFINES="$FDEFINES -DMKL -DOPENMP" -fi - -if test "$OMP_COMPAT" = "YES" -then - FDEFINES="$FDEFINES -DOMP_COMPAT" -fi - -# -D_MSCMARC -FDEFINES="$FDEFINES -D_MSCMARC $DEBUG_OPT $MARC_SIMUFACT" -CDEFINES="$CDEFINES -D_MSCMARC $C_DEBUG_OPT $I8CDEFINES" - -if test "$AEM_DLL" -eq 1 -then - FDEFINES="$FDEFINES -D_AEMNL -DAAA" - CDEFINES="$CDEFINES -D_AEMNL -DAAA" -fi - -CINCL="-I$MARC_SOURCE/mdsrc -I$MARC_SOURCE/csource $METIS -I$LAPI_IMPORTS/common/include" -if test "$_OEM_NASTRAN" -ne 0 -then - CINCL="$CINCL -I../../include" -fi - -CC_OPT= -if test "$MTHREAD" = "OPENMP" -then - CC_OPT=" $CC_OPT -qopenmp" -fi - -CC="icc -c $CC_OPT -O1 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCLOW="icc -c $CC_OPT -O0 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -CCHIGH="icc -c $CC_OPT -O3 $I8DEFINES -DLinux -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - -if test "$MARCDEBUG" = "ON" -then - CC="icc -c $CC_OPT -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCLOW="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " - CCHIGH="icc $CC_OPT -c -DLinux $I8DEFINES -DLINUX -DLinux_intel $CDEFINES $CINCL $SOLVERFLAGS $OPENSSL_INCLUDE " -fi - -LOAD_CC="icc $CC_OPT -O1 -DLinux -DLINUX -DLinux_intel" -CCT="$CC" -CCTLOW="$CCLOW" -CCTHIGH="$CCHIGH" - -#PROFILE="-Mprof=func" -#PROFILE="-Mprof=lines" -#PROFILE="-Mprof=func,mpi" -PROFILE= -#PROFILE="-init=snan,arrays -CB -traceback -fpe0 -fp-stack-check -check all -check uninit -ftrapuv" -if test "$MARCCODECOV" = "ON" -then -PROFILE="-prof-gen=srcpos" -fi -if test "$MARCCODEPROF" = "ON" -then -PROFILE=" $PROFILE -pg" -fi - -FORT_OPT="-c -assume byterecl -safe_cray_ptr -mp1 -WB -fp-model source" -if test "$MTHREAD" = "OPENMP" -then - FORT_OPT=" $FORT_OPT -qopenmp" - if test "$OMP_COMPAT" = "YES" - then - FORT_OPT=" $FORT_OPT -qopenmp-threadprivate=compat" - fi -else -# FORT_OPT=" $FORT_OPT -auto " - FORT_OPT=" $FORT_OPT -save -zero" -fi -if test "$MARCHDF" = "HDF"; then - FORT_OPT="$FORT_OPT -DMARCHDF=$MARCHDF $HDF_INCLUDE" -fi - -FORTLOW="$FCOMP $FORT_OPT $PROFILE -O0 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTRAN="$FCOMP $FORT_OPT $PROFILE -O1 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" -FORTNA="$FCOMP $FORT_OPT -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -# for compiling free form f90 files. high opt, integer(4) -FORTF90="$FCOMP -c -O3" - -if test "$MARCDEBUG" = "ON" -then - FORTLOW="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTRAN="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTHIGH="$FCOMP $FORT_OPT $PROFILE -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" - FORTNA="$FCOMP $FORT_OPT -fno-alias $I8FFLAGS -I$MARC_SOURCE/common \ - $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM" -fi - -FORTLOWT="$FORTLOW" -FORTRANT="$FORTRAN" -FORTHIGHT="$FORTHIGH" - -FORTRANMNF="$FCOMP -c $FDEFINES " -CCMNF="icc -c -O1 -DLinux -DLINUX -DLinux_intel -Dport2egcs -I$MARC_SOURCE/marctoadams/mnf/include -D_LARGEFILE64_SOURCE" - -if test $MPITYPE != none -then - if test $MPITYPE = hpmpi - then - LOAD="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - LOADT="$MPI_ROOT/bin/$FCOMPMPI ${LOADOPTIONS} -L$MPI_ROOT/lib/$ARCHITECTURE $PROFILE $LINK_OPT -o " - fi -# Uncomment the following lines to turn on the tracer and commnet out the next 5 lines -# if test $MPITYPE = intelmpi -# then -# INCLUDEMPI="-I$MPI_ROOT/include -I$VT_ROOT/include" -# LOAD="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# LOADT="$MPI_ROOT/bin/$FCOMPMPI $PROFILE $INCLUDEMPI -g -t=log $LINK_OPT -o " -# fi - if test $MPITYPE = intelmpi - then - LOAD="ifort $PROFILE $LINK_OPT -o " - LOADT="ifort $PROFILE $LINK_OPT -o " - fi -else - LOAD="$FCOMP $LINK_OPT -o " - LOADT="$FCOMP $LINK_OPT -o " -fi - -if test "$MARC_DLL" = MARC_DLL -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide -lpthread" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - -if test "$AEM_DLL" -eq 1 -then - FORTLOW="$FORTLOW -fpp -fPIC" - FORTRAN="$FORTRAN -fpp -fPIC" - FORTHIGH="$FORTHIGH -fpp -fPIC" - FORTRANMNF="$FORTRANMNF -fpp -fPIC" - CC="$CC -fPIC" - CCMNF="$CCMNF -fPIC" - LINK_EXE_MARC="-L$MARC_LIB -lmarc -L$MARC_LIB_SHARED -lguide" - LINK_MARC_DLL="-shared -fPIC" - LOAD_DLL=$LOAD - LOADT_DLL=$LOADT - EXT_DLL="so" -fi - - -XLIBS="-L/usr/X11/lib -lX11 " - -# -# define archive and ranlib syntax -# - -ARC="ar rvl" -ARD="ar dvl" -ARX="ar xl" -RAN="" - -# -# choose which libraries you want to use ( e.g. blas ) -# - -if test "$VKISOLVER" = VKI -then - VKISOLVERLIBS="$MARC_LIB/vkisolver.a" -else - VKISOLVERLIBS= -fi - -if test "$CASISOLVER" = CASI -then - CASISOLVERLIBS="$CASILIB_DIR/libmarccasi.a $CASILIB_DIR/libcasi.a" -else - CASISOLVERLIBS= -fi - -MF2SOLVERLIBS= -if test "$MF2SOLVER" = MF2PARALLEL -then - MF2SOLVERLIBS="$MARC_LIB/mf2parallel/libseq.a \ - $MARC_LIB/mf2parallel/libsym.a \ - $MARC_LIB/mf2parallel/libmet.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libmf2.a \ - $MARC_LIB/mf2parallel/libgauss.a \ - $MARC_LIB/mf2parallel/libnum.a \ - $MARC_LIB/mf2parallel/libutl.a \ - $MARC_LIB/mf2parallel/libr8.a \ - $MARC_LIB/mf2parallel/libz.a " -fi - -if test "$MUMPSSOLVER" = MUMPS -then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps.a" - if test $MPITYPE = none - then - MUMPSSOLVERLIBS2= - echo hello > /dev/null - fi - if test $MPITYPE = intelmpi - then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_intelmpi.a" - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a " - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a " - fi - fi - if test $MPITYPE = hpmpi - then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_hpmpi.a" - if test "$MARC_INTEGER_SIZE" = "i4" ; then - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_lp64.a" - else - MUMPSSOLVERLIBS2=" $MARC_MKL/libmkl_blacs_intelmpi_ilp64.a" - fi - fi -else - MUMPSSOLVERLIBS= - MUMPSSOLVERLIBS2= -fi - -if test "$BCSGPUSOLVER" = BCSGPU -then - BCSSOLVERLIBS="${BCSLIB_DIR}/bcsgpulib.a " - MARCCUDALIBS1="-L${BCSLIB_DIR}/cuda_dummy -lmarccuda " - MARCCUDALIBS2="-L${BCSLIB_DIR}/cuda -lmarccuda " - MARCCUDALIBS=$MARCCUDALIBS1 -else - BCSSOLVERLIBS="${MARC_LIB}/bcslib.a " -fi -if test "$AEM_DLL" -eq 1 -then - BCSSOLVERLIBS= -fi - -if test "$MARC_INTEGER_SIZE" = "i4" ; then - MKLLIB="$MARC_MKL/libmkl_scalapack_lp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_lp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -else - MKLLIB="$MARC_MKL/libmkl_scalapack_ilp64.a -Wl,--start-group $MARC_MKL/libmkl_intel_ilp64.a $MARC_MKL/libmkl_intel_thread.a $MARC_MKL/libmkl_core.a $MUMPSSOLVERLIBS2 -Wl,--end-group" -fi - -SECLIBS="-L$MARC_LIB -llapi" - -SOLVERLIBS="${BCSSOLVERLIBS} ${VKISOLVERLIBS} ${CASISOLVERLIBS} ${MF2SOLVERLIBS} \ - $MKLLIB -L$MARC_MKL -liomp5 \ - $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/kdtree2.a $HDF_LIBS" - -SOLVERLIBS_DLL=${SOLVERLIBS} -if test "$AEM_DLL" -eq 1 -then -SOLVERLIBS_DLL="$MKLLIB -L$MARC_MKL -liomp5 $MARC_LIB/blas_src.a" -fi -MRCLIBS="$MARC_LIB/clib.a ${CASISOLVERLIBS}" -MRCLIBSPAR="$MARC_LIB/clib.a" -STUBS="$MARC_LIB/stubs.a " -MNFLIBS="$MARC_LIB/libmnf.a" -MDUSER="$MARC_LIB/md_user.a" -if test "X$MARC_SIMUFACT" = "X-DSIMUFACT" || test -f "$MARC_LIB/libMBA_Grain.so" -then - SFLIB="-L$SFMATDIR -lMBA_Grain $SFMATDIR/sfclib.a " -else - SFLIB=" " -fi - -OPENMP="-qopenmp" - -if test "$AEM_DLL" -eq 1 -then - LOAD_DLL=$LOAD - OPENMP= - LIBMNF= - OPENSSL=NONE -fi - -SYSLIBS=" $OPENMP -lpthread -shared-intel -cxxlib" - -# Uncomment the following lines to turn on the trace and comment out the next 4 lines -# if test $MPITYPE = intelmpi -# then -# SYSLIBS="-L${VT_ROOT}/lib -lVT -ldwarf -lelf -lm -lpthread \ -# -L${MPI_ROOT}/lib64 -lmpi -lmpiif -lmpigi -lrt" -# fi -if test $MPITYPE = intelmpi -then - SYSLIBS="-L${MPI_ROOT}/lib -lmpi_mt -lmpifort -lrt $OPENMP -threads -lpthread -shared-intel -cxxlib" -fi - - -SYSLIBSPAR=" " - -MARC_DLL_CODES="runmarc.f" - - -BLAS_SRC="dzero.f icopy.f izero.f" -if test "$_OEM_NASTRAN" -ne 0 -then - if test "$MARC_INTEGER_SIZE" = "i4" ; then - BLAS_SRC="$BLAS_SRC dsctr.f zsctr.f dzasum.f daxpyi.f zaxpyi.f dgthr.f zgthr.f" - else - BLAS_SRC="ALL" - fi -fi - -LOW_OPT_CODES="are163.f contro.f ndext.f omarc.f omarca.f omarcb.f omarcc.f \ - omars.f fixbc.f triang.f bet049.f norst3.f eldata.f \ - elec*.f elct*.f fmeig.f oada00.f ogeig.f updtrbe2.f cycrota.f \ - cordef.f ogpk.f ogtan.f eldam.f formrbe3.f \ - inertie.f em_sso072.f cn_fol3d_qpatch6.f cosim_begin.f" -if test "$MARC_INTEGER_SIZE" = "i8" ; then - LOW_OPT_CODES="$LOW_OPT_CODES bbcseg.f" -fi - -HIGH_OPT_CODES="dpsmsa1.f dpsmsa2.f dpsmsa3.f dpsmsa4.f dpsmsa5.f dpsmsa6.f \ - dpsmsa7.f dpsmsa8.f dpsmsa9.f dpsmsa10.f dpsmsa11.f dpsmsa12.f \ - dpsmsa13.f dpsmsa14.f dpsmsa15.f dpsmsa16.f dpsmsah.f tpsmsah.f cn_qsort4_11.f " - - - -MAXNUM=1000000 diff --git a/installation/mods_MarcMentat/2019/Marc_tools/run_damask_hmp b/installation/mods_MarcMentat/2019/Marc_tools/run_damask_hmp deleted file mode 100644 index 4a9200e8b..000000000 --- a/installation/mods_MarcMentat/2019/Marc_tools/run_damask_hmp +++ /dev/null @@ -1,4105 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - - -# getting user subroutine file name -found=0 -for i in "$@"; do - if test $found = 1; then - DAMASK_USER=$i - found=0 - fi - case $i in - -u* | -U*) - found=1 - ;; - esac -done -# sourcing include_linux64 (needs DAMASK_USER to be set) -. $MARC_INCLUDE - -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\+\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$SFMATDIR:$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usernoext= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto= -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - echo - echo warning: the option -au is no longer supported and will be ignored - echo - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_intelmpi.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - if test ! -f $user - then - error="$error -user subroutine file $user not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" -fi -fi - -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($user)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# -# add DAMASK options for linking - DAMASK="-lstdc++" - - if test "$user" - then - program=$usernoext.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$usernoext.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -############################################################################## -# run marc using valgrind # -############################################################################## -#RUN_JOB="valgrind $RUN_JOB" -#RUN_JOB="valgrind --read-var-info=yes --gen-suppressions=yes $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=all -v $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=yes --error-limit=no $RUN_JOB" -############################################################################## - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$usermoext.o - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test $MACHINENAME = "CRAY" - then - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTHIGHMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTHIGHMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTHIGHMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTHIGHMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - $RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2019/Marc_tools/run_damask_lmp b/installation/mods_MarcMentat/2019/Marc_tools/run_damask_lmp deleted file mode 100644 index ea6872059..000000000 --- a/installation/mods_MarcMentat/2019/Marc_tools/run_damask_lmp +++ /dev/null @@ -1,4105 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - - -# getting user subroutine file name -found=0 -for i in "$@"; do - if test $found = 1; then - DAMASK_USER=$i - found=0 - fi - case $i in - -u* | -U*) - found=1 - ;; - esac -done -# sourcing include_linux64 (needs DAMASK_USER to be set) -. $MARC_INCLUDE - -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\+\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$SFMATDIR:$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usernoext= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto= -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - echo - echo warning: the option -au is no longer supported and will be ignored - echo - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_intelmpi.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - if test ! -f $user - then - error="$error -user subroutine file $user not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" -fi -fi - -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($user)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# -# add DAMASK options for linking - DAMASK="-lstdc++" - - if test "$user" - then - program=$usernoext.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$usernoext.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -############################################################################## -# run marc using valgrind # -############################################################################## -#RUN_JOB="valgrind $RUN_JOB" -#RUN_JOB="valgrind --read-var-info=yes --gen-suppressions=yes $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=all -v $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=yes --error-limit=no $RUN_JOB" -############################################################################## - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$usermoext.o - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test $MACHINENAME = "CRAY" - then - $DFORTLOWMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTLOWMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_lmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTLOWMP $user || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTLOWMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_lmp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTLOWMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTLOWMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - $RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2019/Marc_tools/run_damask_mp b/installation/mods_MarcMentat/2019/Marc_tools/run_damask_mp deleted file mode 100644 index 8aa27505c..000000000 --- a/installation/mods_MarcMentat/2019/Marc_tools/run_damask_mp +++ /dev/null @@ -1,4105 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - - -# getting user subroutine file name -found=0 -for i in "$@"; do - if test $found = 1; then - DAMASK_USER=$i - found=0 - fi - case $i in - -u* | -U*) - found=1 - ;; - esac -done -# sourcing include_linux64 (needs DAMASK_USER to be set) -. $MARC_INCLUDE - -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\+\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$SFMATDIR:$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usernoext= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto= -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - echo - echo warning: the option -au is no longer supported and will be ignored - echo - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_intelmpi.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - if test ! -f $user - then - error="$error -user subroutine file $user not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" -fi -fi - -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $user -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($user)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=$value - case $user in - \/*) - ;; - *) - user=`pwd`/$user - ;; - esac - usernoext=$user - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` - usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# -# add DAMASK options for linking - DAMASK="-lstdc++" - - if test "$user" - then - program=$usernoext.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$usernoext.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -############################################################################## -# run marc using valgrind # -############################################################################## -#RUN_JOB="valgrind $RUN_JOB" -#RUN_JOB="valgrind --read-var-info=yes --gen-suppressions=yes $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=all -v $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=yes --error-limit=no $RUN_JOB" -############################################################################## - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$usermoext.o - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test $MACHINENAME = "CRAY" - then - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTRANMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTRANMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user on host `hostname`" - fi - userobj=$usernoext.o - if test $MACHINENAME = "CRAY" - then - $DFORTRANMP $user || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $DFORTRANMP $user -o $userobj || \ - { - echo "$0: compile failed for $user" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $DAMASK \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null -/bin/rm $DIRJOB/*.mod 2>/dev/null -/bin/rm $DIRJOB/*.smod 2>/dev/null -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - $RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi -fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=$usernoext - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2019/Marc_tools/run_marc.original b/installation/mods_MarcMentat/2019/Marc_tools/run_marc.original deleted file mode 100644 index 8cad62751..000000000 --- a/installation/mods_MarcMentat/2019/Marc_tools/run_marc.original +++ /dev/null @@ -1,4183 +0,0 @@ -#!/bin/ksh -############################################################################## -# # -# run_marc - run a marc job # -# ------------------------- # -# # -# usage: run_marc -j jid { options } # -# # -# where standard options are: required: defaults: # -# -------------------------- # -# # -# -j* jid job id number. ** YES ** . # -# -pr* prog program name. . marc # -# -v* y|n do or do not verify inputs. . yes # -# -q* s|l|v|b|f batch queue name or background, . short # -# foreground. # -# -b* as alternative to option -q* # -# # -# ( batch queues only : # -# -pq* intra queue priority. . . # -# -at DATE/TIME delay start of job. . . # -# format : January,1,1990,12:31 # -# or : today,5pm # -# -cpu* secs job CPU limit . . ) # -# # -# -r* rid restart file job id. . . # -# -si* sid substructure file id. . . # -# -pi* post post file job id. . . # -# -de* did defaults file . no # -# -vf vid viewfactor . no # -# # -# -u* user user subroutine. . . # -# -obj obj user objects or libraries. . . # -# -sa* y|n do or do not save load module. . no # -# -me manual remeshing control . no # -# -ml memory limit in Mbyte # -# -mo This option is deprecated. As of Marc 2015, only # -# the integer*8 version is available. # -# -mpi selects MPI version # -# each platform has a default MPI version and some # -# have an alternative version. see the include file # -# for the respective platform # -# MPI_DEFAULT defines the default MPI version # -# MPI_OTHER defines versions one can switch to # -# -dcoup for contact decoupling # -# currently not supported # -# -dir directory where the job i/o should take place. # -# defaults to current directory. # -# -sdir directory where scratch files are created # -# defaults to current directory. # -# # -# -alloc only perform memory allocation test, no analysis # -# -list y only list options in the input file, no analysis # -# -fe num set feature number "num" for the run. only one allowed # -# -dytran flag to switch from Dytran to Marc # -# dytran = 0, program will run w/o Marc-Dytran Switch # -# = 1, program will restart Marc after Dytran run # -# >= 2, Not supported yet. # -# currently not supported # -# -ou force analysis to use out-of-core control # -# =0, not used # -# =1, element storage out-of-core # -# -dll run marc using shared library libmarc.so and exe_marc # -# =1, used # -# =2, do not free streaming input memory # -# =3, run with marc input deck # -# -trk run marc for post-tracking # -# -gpuid run marc using GPGPU capability # -# specify gpuid on to be used in the analysis. Multiple # -# IDs may be assigned for DDM runs. # -# Separate a list of IDs with a colon. Each DMP # -# process will be assigned a GPU ID in round robin fastion# -# = 0 # -# = 0:1 etc... # -# # -# where parallel options are: # -# -------------------------- # -# # -# itree, host, and comp options are available for the domain # -# decomposition only. # -# MARC_NUMBER_OF_THREADS, nthread, and dir options always available. # -# # -# # -# -nprocd number of domains. # -# defaults to single domain solution. # -# -nprocds number of domains if single input file. # -# defaults to single domain solution. # -# -nps same as -nprocds. # -# -nsolver number of solver tasks for solver types 12 and 13 # -# these are distributed tasks operating via MPI # -# -nthread_elem number of threads for element assembly and recovery # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by element assembly # -# recovery. # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_elem option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_elem specified. # -# -nthread_solver number of threads for solver types 6, 8, and 11 # -# = 0: use defaults. # -# defaults to 1 for single domain solution. # -# defaults to number of domains for multi-domain # -# solution. # -# > 1: number of threads to be used by 6, 8, and 11 # -# Also can be set through MARC_NUMBER_OF_THREADS # -# environment variable. # -# if both specified, -nthread_solver option will be used. # -# defaults if neither MARC_NUMBER_OF_THREADS environment # -# variable set nor -nthread_solver specified. # -# -nthread Same as -nthread_solver. # -# -itree message passing tree type for domain decomposition. # -# for debugging purposes; should not normally be used. # -# -host hostfile name for distributed execution on network. # -# defaults to no hostfile, unless jobid.defhost exists. # -# if jobid.defhost exists, only -np(s) necessary # -# -comp* y|n to be used with user routines on a network of # -# incompatible machines. # -# if set to no, a separate executable will be created # -# for each machine on the network. # -# if set to yes, the executable located on the machine # -# from which marc is started will be used on all machines.# -# defaults to no if O/S versions different on machines. # -# # -# -ci y|n copy input files to remote hosts (default: yes) # -# if "yes", input files are automatically copied to # -# remote hosts for a network run if necessary. # -# -cr y|n copy post files from remote hosts (default: yes) # -# if "yes", post files are automatically copied back from # -# remote hosts for a network run if necessary. # -############################################################################## -# set DIR to the directory in which this script is -REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" -DIR=`dirname $REALCOM` -# make sure DIR has an absolute path -case $DIR in - \/*) - ;; - *) - DIR=`pwd`/$DIR - ;; -esac -DIRSCRIPT=$DIR -AWK=awk -ARCH=`uname -a | cut -f 1 -d " "` -# Sun has a bad awk, use nawk instead -if test $ARCH = "SunOS" -then - AWK=nawk -fi -BASENAME=basename -# Sun has an incorrect /bin/basename, check if /usr/ucb/basename exists -if test $ARCH = "SunOS" -then - if test -x /usr/ucb/basename - then - BASENAME=/usr/ucb/basename - fi -fi - -# echo command line in the case of ECHO_COMMAND is true -if test "$ECHO_COMMAND" = true ; then - echo command "$0" "$@" -fi - -# -# "mode" selects version, i4 or i8 -# default is i4 -# this can be changed by a file run_marc_defaults -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MODE i8 -# it can also be set by the environmental variable MARC_INTEGER_SIZE -# and by the command line option "-mo" -# -mode= -modeerror= -modeoption= -if test -f $DIRSCRIPT/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $DIRSCRIPT/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $DIRSCRIPT/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $DIRSCRIPT/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -f $HOME/run_marc_defaults; then - line=`$AWK '{if ($1 == "MARC_MODE") {print $1}}' $HOME/run_marc_defaults` - if test "$line" = "MARC_MODE"; then - echo - echo warning: the option MARC_MODE is deprecated, as of Marc 2015, only the integer*8 version is available - echo - line= - fi - line=`$AWK '{if ($1 == "MARC_MODE") {print $2}}' $HOME/run_marc_defaults` - line=`echo $line | $AWK '{print $NF}'` - if test "$line" = "i4"; then - modeerror="defaults file $HOME/run_marc_defaults used mode $line ; this must be i8" - modeoption=error - echo $modeerror - fi - if test "$line" = "i8"; then - mode=i8 - fi -fi -if test -n "$MARC_INTEGER_SIZE" ; then - mode=$MARC_INTEGER_SIZE -fi -if test -z "$mode" ; then - mode=i8 -fi -case $mode in - i4) - modeerror="bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - modeoption=error - echo $modeerror - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo "bad value for MARC_INTEGER_SIZE variable; only i8 is supported." - exit - ;; -esac - -setmode=false -for arg in $* ; do - if $setmode ; then - mode=$arg - case $mode in - i4) - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - ;; - i8) - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - ;; - *) - echo " " - echo "error, version mode must be i8" - echo " " - echo " use -mo i8 " - echo " " - exit - ;; - esac - setmode=false - fi - if [ ${arg}X = -moX -o ${arg}X = -MOX ] ; then - echo - echo warning: the option -mo is deprecated, as of Marc 2015, only the integer*8 version is available - echo - setmode=true - fi - if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - MARC_INTEGER_SIZE=i8 - export MARC_INTEGER_SIZE - fi - if [ ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - modeerror="bad value for mode option; only i8 is supported." - modeoption=error - echo - echo $modeerror - echo - fi -done - -# set to i4 version for 32 bit Linux -if test "`uname -s`" = "Linux"; then - if test "`uname -m`" = "i686"; then - mode=i4 - MARC_INTEGER_SIZE=i4 - export MARC_INTEGER_SIZE - fi -fi - - -. "$DIR/getarch" - -. $MARC_INCLUDE -# - -# -# Dynamically determine the echo syntax -# - -case "`echo '\c'`" in - '\c') - ECHO='echo -n' - ECHOTXT=' ' - ;; - *) - ECHO='echo' - ECHOTXT=' \c' - ;; -esac - -# -# Variables for the MARC environment -# - -PRODUCT="Marc" -EXITMSG=$MARC_TOOLS/MESSAGES -export EXITMSG -FLEXDIR=$DIR/../flexlm/licenses -export FLEXDIR -TIMCHK=3600 -export TIMCHK -BINDIR=$MARC_BIN -export BINDIR -AFMATDAT=$MARC_RUNTIME/AF_flowmat/ -export AFMATDAT -export MESHERDIR -MSC_LICENSE_FINPROC=0 -export MSC_LICENSE_FINPROC -# -# define directory path to global unified material database -# -MATFILE= -export MATFILE - -# -# define memory limit -# first set to MEMLIMIT from include -# -ml option overrules if specified -memlimit=$MEMLIMIT -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -# -if test $MACHINENAME = "HP" -then - SHLIB_PATH=$MARC_LIB:$MARC_LIB_SHARED:$SHLIB_PATH - export SHLIB_PATH -fi -# the one for IBM is defined futher down - -LD_LIBRARY_PATH=$MARC_LIB_SHARED:$LD_LIBRARY_PATH -if test -f "/etc/redhat-release"; then - ver=`cat /etc/redhat-release | sed 's/.* release \([0-9]\).\([0-9]\+\) .*/\1\2/'` - case "$ver" in - 6*) LD_LIBRARY_PATH="${MARC_LIB_SHARED}rh67:$LD_LIBRARY_PATH" ;; - esac -fi -LD_LIBRARY_PATH=$MARC_LIB:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$MESHERDIR:$LD_LIBRARY_PATH -LD_LIBRARY_PATH=$SFMATDIR:$LD_LIBRARY_PATH -LD_LIBRARY64_PATH=$MARC_LIB:$LD_LIBRARY64_PATH -LD_LIBRARYN32_PATH=$MARC_LIB:$LD_LIBRARYN32_PATH -export LD_LIBRARY_PATH -export LD_LIBRARY64_PATH -export LD_LIBRARYN32_PATH - -atexit() { -kill -15 $$ -# -if test $MPITYPE = "myrinet" -then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi -fi -} - -trap "atexit" 2 - -# -# defaults -# - -prog=marc -exefile=marc -jid= -rid= -pid= -sid= -did= -vid= -user= -usersubname= -objs= -qid=background -cpu= -priority= -att= -trk= -verify=yes -prgsav=no -rmdll=no -cpdll=no -progdll= -pathdll= -error= -nprocd=0 -nprocdddm=1 -nprocdddmprint= -icreated=0 -nprocdarg= -nsolver=0 -nsolverarg=-ns -if test $nprocds -then - if test $nprocds -gt 1 - then - nprocdddm=$nprocds - nprocdddmprint=$nprocds - icreated=1 - nprocdarg=-nprocds - fi -fi -ntprint=0 -nt=-1 -nte=-1 -nts=-1 -ntarg=-nt -ntearg=-nte -ntsarg=-nts -nteprint= -ntsprint= -gpuids= -nauto= -ndcoup=0 -ndytran=0 -noutcore=0 -dllrun=0 -mesh=0 -itree=0 -iam= -ddm_arc=0 -link= -trkrun=0 -DIRJOB=`pwd` -DIRSCR=$DIRJOB -DIRSCRSET= -autoforge=0 -dotdat=.dat -dotdefhost=.defhost -host= -numhost= -mfile= -userhost= -makebdf= -cpinput=yes -cpresults=yes -marcdll=libmarc.$EXT_DLL -# define hostname and strip off extensions (alpha.aaa.com) -thishost=`hostname` -thishost=${thishost%%.*} -compatible=unknown -numfield=1 -justlist= -feature= -mpioption=false -iprintsimufact= -MDSRCLIB=$MARC_LIB/mdsrc.a -# -# check run_marc_defaults file for default MPI setting -# located in the tools directory of the Marc installation -# or in the user's home directory -# format: -# MARC_MPI -# -value= -file= -if test -f $DIRSCRIPT/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $DIRSCRIPT/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$DIRSCRIPT/run_marc_defaults - fi -fi -if test -f $HOME/run_marc_defaults; then - value=`$AWK '{if ($1 == "MARC_MPI") {print $2}}' $HOME/run_marc_defaults` - value=`echo $value | $AWK '{print $NF}'` - if test -n "$value"; then - file=$HOME/run_marc_defaults - fi -fi -if test -n "$value"; then - MARC_MPITYPE=$value - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - echo " " - echo " error, incorrect option for MARC_MPI" - echo " defined in $file: $MARC_MPITYPE" - echo " valid options: $MPI_DEFAULT $MPI_OTHER" - echo " " - exit - fi - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - fi -fi -# -# -# allow scratch directory to be specified with environmental variable -# MARCSCRATCH -if test $MARCSCRATCH -then - if test -d $MARCSCRATCH - then - DIRSCR=$MARCSCRATCH - else - echo "error, scratch directory '$MARCSCRATCH'" - echo " specified via environmental variable MARCSCRATCH does not exist" - exit - fi -fi -# -############################################################################## -# parse input - arguments always come in pairs # -############################################################################## - -arg=$1 -if [ ${arg}X = -i8X -o ${arg}X = -I8X ] ; then - shift - arg=$1 -fi -while [ -n "$arg" ] -do - shift - value=$1 - case $arg in - -al* | -AL*) - LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - $MARC_BIN/marc -alloc 1 - exit - ;; - -li* | -LI*) - justlist=yes - ;; - -fe* | -FE*) - feature=$value - - ;; - -pr* | -PR*) - if test `dirname $value` = '.' - then - prog=`$BASENAME $value .marc` - progdll=`$BASENAME $value` - else - prog=`dirname $value`/`$BASENAME $value .marc` - progdll=`dirname $value`/`$BASENAME $value` - fi - prdir=`dirname $value` - case $prdir in - \/*) - ;; - *) - prog=`pwd`/$prdir/$prog - ;; - esac - ;; - -j* | -J*) - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - ;; - -r* | -R*) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - -si* | -SI*) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - -pi* | -PI*) - if test -f $value.t19 - then - pid=`$BASENAME $value .t19` - else - pid=`$BASENAME $value .t16` - fi - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - -bdf | -BDF) - makebdf=1 - ;; - -de* | -DE*) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - -vf | -VF) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - -u* | -U*) - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user - basefile=`$BASENAME $value` - if test ${basefile##*.} = f - then - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user.f - elif test ${basefile##*.} = F - then - user=`dirname $value`/`$BASENAME $value .F` - usersubname=$user.F - elif test ${basefile##*.} = f90 - then - user=`dirname $value`/`$BASENAME $value .f90` - usersubname=$user.f90 - elif test ${basefile##*.} = F90 - then - user=`dirname $value`/`$BASENAME $value .F90` - usersubname=$user.F90 - fi - case $user in - \/*) - ;; - *) - user=`pwd`/$user - usersubname=`pwd`/$usersubname - ;; - esac - if test ! -f $usersubname - then - if test -f $usersubname.f - then - usersubname=$usersubname.f - elif test -f $usersubname.F - then - usersubname=$usersubname.F - elif test -f $usersubname.f90 - then - usersubname=$usersubname.f90 - elif test -f $usersubname.F90 - then - usersubname=$usersubname.F90 - fi - fi - ;; - -obj | -OBJ) - objs="$value" - ;; - -q* | -Q*) - qid=$value - ;; - -b* | -B*) - case $value in - y* | Y*) - qid=background - ;; - n* | N*) - qid=foreground - ;; - *) - ;; - esac - ;; - -at | -AT) - att=$value - ;; - -cpu* | -CPU*) - cpu=$value - ;; - -pq | -PQ*) - priority=$value - ;; - -v* | -V*) - verify=$value - ;; - -sa* | -SA*) - prgsav=$value - ;; - -np* | -NP*) - nprocdddm=$value - nprocdddmprint=$value - case $arg in - -nps* | -NPS* | -nprocds* | -NPROCDS*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - case $arg in - -np | -NP | -nprocd | -NPROCD) - icreated=0 - nprocdarg=-nprocd - ;; - esac - ;; - -ns* | -NS*) - nsolver=$value - ;; - -nt* | -NT*) - case $arg in - -nte | -NTE | -nthread_e* | -NTHREAD_E*) - nte=$value - ;; - esac - case $arg in - -nts | -NTS | -nthread_s* | -NTHREAD_S*) - nts=$value - ;; - esac - case $arg in - -nt | -NT | -nth* | -NTH* | -nthread* | -NTHREAD*) - nt=$value - ;; - esac - ;; - -gp* | -GP*) - gpuids=$value - ;; - -it* | -IT*) - itree=$value - ;; - -iam | -IAM) - iam=$value - case $value in - sfg | sfm | sim) - iprintsimufact=true - ;; - esac - ;; - -au* | -AU*) - nauto=$value - echo - echo warning: the option -au is no longer supported and will be ignored - echo - ;; - -dc* | -DC*) - ndcoup=$value - ;; - -dy* | -DY*) - ndytran=$value - ;; - -ou* | -OU*) - noutcore=$value - ;; - -dll | -DLL) - dllrun=$value - ;; - -trk | -TRK) - trkrun=$value - ;; - -ddm | -DDM) - ddm_arc=$value - ;; - -me | -ME ) - mesh=$value - ;; - -ml | -ML ) - memlimit=$value - ;; - -mo | -MO ) - ;; - -mpi | -MPI ) - mpioption=true - MARC_MPITYPE=$value - if test "$value" != "$MPI_DEFAULT"; then - exefile=marc_$value - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a_$value - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_$value.a" - fi - else - exefile=marc - . $MARC_INCLUDE - MDSRCLIB=$MARC_LIB/mdsrc.a - if test "$MUMPSSOLVER" = MUMPS; then - MUMPSSOLVERLIBS="$MUMPSLIB_DIR/libmumps_intelmpi.a" - fi - fi - ;; - -dir* | -DIR*) - DIRJOB=$value - case $DIRJOB in - \/*) - ;; - *) - DIRJOB=`pwd`/$DIRJOB - ;; - esac - if test -z "$DIRSCRSET" - then - DIRSCR=$DIRJOB - fi - ;; - -sd* | -SD*) - DIRSCR=$value - DIRSCRSET=yes - case $DIRSCR in - \/*) - ;; - *) - DIRSCR=`pwd`/$DIRSCR - ;; - esac - ;; - -ho* | -HO*) - host=$value - ;; - -co* | -CO*) - compatible=$value - ;; - -ci* | -CI*) - cpinput=$value - ;; - -cr* | -CR*) - cpresults=$value - ;; - *) - error="$error -$arg: invalid option" - break - ;; - esac - case $value in - -*) - error="$error -$arg: invalid name $value" - break - ;; - esac - shift - arg=$1 - if [ ${arg}X = -i8X -o ${arg}X = -I8X -o ${arg}X = -i4X -o ${arg}X = -I4X ] ; then - shift - arg=$1 - fi -done -argc=`expr $# % 2` -if test $argc -eq 1 -then -# -# odd number of arguments -# - error="$error -argument list incomplete" -fi - -if test $nprocdddm -gt 0 -then -nprocd=$nprocdddm -fi - -if test $nsolver -gt 0 -then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi -fi -# Set defaults -if test $nt -eq -1 -then -nt=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nt -lt 0 -then -nt=0 -fi -if test $nte -eq -1 -then -nte=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nte -lt 0 -then -nte=0 -fi -if test $nts -eq -1 -then -nts=${MARC_NUMBER_OF_THREADS:-0} -fi -if test $nts -lt 0 -then -nts=0 -fi -# -# set number of element loop threads -# -ntprint=$nt -nteprint=$nte -# copy from -nprocd[s] -if test $nprocdddm -gt 1 -then - nteprint=$nprocdddm -fi -# override with -nthread_elem option -if test $nte -ne 0 -then -nteprint=$nte -fi -# check for minimum 1 threads per processes for DDM -if test $nprocdddm -gt 1 -then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi -fi -nte=$nteprint -# -# set number of Solver threads -# -ntsprint=$nts -# copy from -nthread or -nprocd[s] -if test $ntprint -ne 0 -then - ntsprint=$ntprint -else - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -fi -# override with -nthread_solver option -if test $nts -ne 0 -then - ntsprint=$nts -fi -# check for minimum 1 threads per solver process. -if test $nsolver -lt $nprocdddm -then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi -else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi -fi -if test $ntsprint -eq 1 -then - set ntsprint=0 -fi -nts=$ntsprint - -# set stack size for multi-threading. -export KMP_MONITOR_STACKSIZE=7M -export OMP_STACKSIZE=7M - -# -# deprecate -nthread option at arugment of marc -nt=0 -# Reset nprocdddmm, nsolver and threads if not given. -if test $nprocdddm -eq 0 -then - nprocdarg= -fi -if test $nprocdddm -eq 0 -then - nprocdddmprint= -fi -if test $nprocdddm -eq 0 -then - nprocdddm= -fi - -nsolverprint=$nsolver -if test $nsolver -eq 0 -then - nsolverprint= -fi -# end of threads setting. -gpuoption= -if test "$gpuids" = "" ; then - gpuoption= -else - gpuoption="-gp $gpuids" -fi - -if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH -else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH -fi -# Linux 64 + HPMPI, Below code is taken from include_linux64 -if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" -then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" -fi - -if test $nprocd -gt 1; then - if test -f $jid$dotdefhost; then - if test "$host" = ""; then - host=$jid$dotdefhost - fi - fi - if test -f hostfile_qa_$nprocd; then - if test "$host" = ""; then - host=hostfile_qa_$nprocd - fi - fi -fi - -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$dllrun" -eq 1 || test "$dllrun" -eq 2; then - dotdat=.inp - fi - - if test "$progdll"; then - /bin/cp ${progdll}_$marcdll $DIRJOB/$marcdll - rmdll=yes - pathdll=yes - progdll=${progdll}_$marcdll - else - progdll=$marcdll - fi - - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - pathdll=yes - fi -fi - -############################################################################## -# check parameter validity # -############################################################################## - -while test forever; do - -# -# check for input file existence -# -if test $nprocdddm -gt 1 -a $icreated -eq 0; then - if test ! -f $DIRJID/1$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/1$jid$dotdat not accessible" - fi - fi -else - if test ! -f $DIRJID/$jid$dotdat; then - if test "$jid" != "" ; then - error="$error -input file $DIRJID/$jid$dotdat not accessible" - fi - fi -fi - if test $nprocd -gt 1; then - if test "$host" ; then - if test ! -f $host; then - error="$error -host name file $host not accessible" - fi - fi - fi - -# -# check if the job is already running in the background -# -if test -f $DIRJOB/$jid.pid; then - error="$error -job is already running (the file $jid.pid exists)" -fi - -# -# if the program name is other than marc, then -# assume that this is a program in the users local directory -# - -bd=$MARC_BIN/ - -case $prog in - marc | MARC | $exefile) - program=$exefile - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$usersubname" - then - if test ! -f $usersubname - then - error="$error -user subroutine file $usersubname not accessible" - fi - fi - if test "$objs" - then - missingobjs= - for o in $objs - do - if test ! -f "$o" - then - if test -z "$missingobjs" - then - missingobjs="$o" - else - missingobjs="$missingobjs $o" - fi - fi - done - if test -n "$missingobjs" - then - error="$error -user object/library file(s) $missingobjs not accessible" - fi - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$vid" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRVID/1$vid.vfs - then - error="$error -view factor file $DIRVID/1$vid.vfs not accessible" - fi - else - if test ! -f $DIRVID/$vid.vfs - then - error="$error -view factor file $DIRVID/$vid.vfs not accessible" - fi - fi - fi - if $mpioption - then - notok=true - for i in "$MPI_OTHER"; do - if test "$MARC_MPITYPE" = "$i"; then - notok=false - fi - done - if test "$MARC_MPITYPE" = "$MPI_DEFAULT"; then - notok=false - fi - if $notok; then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE (valid: $MPI_OTHER)" - fi - fi - ;; - *) - program=$prog.marc - case $prog in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - if test "$rid" - then - if test ! -f $DIRRID/$rid.t08 - then - error="$error -restart file $DIRRID/$rid.t08 not accessible" - fi - fi - if test "$pid" - then - if test ! -f $DIRPID/$pid.t16 - then - if test ! -f $DIRPID/$pid.t19 - then - error="$error -post file $DIRPID/$pid.t16 and $DIRPID/$pid.t19 not accessible" - fi - fi - fi - if test "$user" - then - error="$error -program option may not be used with user subroutine" - fi - if test "$objs" - then - error="$error -program option may not be used with user objects or libraries" - fi - if test "$did" - then - if test $nprocdddm -gt 1 -a $icreated -eq 0 - then - if test ! -f $DIRDID/1$did$dotdat - then - error="$error -defaults file $DIRDID/1$did$dotdat not accessible" - fi - else - if test ! -f $DIRDID/$did$dotdat - then - error="$error -defaults file $DIRDID/$did$dotdat not accessible" - fi - fi - fi - if test "$ndcoup" - then - if test $ndcoup -gt 3 - then - error="$error -incorrect option for contact decoupling " - fi - fi - if test "$ndytran" - then - if test $ndytran -gt 1 - then - error="$error -incorrect option for Marc-Dytran Switch " - fi - fi - if $mpioption - then - if test ! -x $MARC_BIN/$exefile - then - error="$error -incorrect option for -mpi option: $MARC_MPITYPE " - fi - fi - ;; -esac - -############################################################################## -# check argument integrity # -############################################################################## - -if test "$jid" -then - : -else - if test "$user" - then -# allow user sub without giving job id - qid=foreground - verify=no - else - error="$error -job id required" - fi -fi - -case $qid in - S* | s*) - qid=short - ;; - L* | l*) - qid=long - ;; - V* | v*) - qid=verylong - ;; - B* | b*) - qid=background - ;; - F* | f*) - qid=foreground - ;; - A* | a*) - qid=at - ;; - *) - error="$error -bad value for queue_id option" - ;; -esac - -case $prgsav in - N* | n*) - prgsav=no - ;; - Y* | y*) - prgsav=yes - ;; - *) - error="$error -bad value for save option" - ;; -esac - -case $verify in - N* | n*) - verify=no - ;; - Y* | y*) - verify=yes - ;; - *) - error="$error -bad value for verify option" - ;; -esac - -case $nprocdddm in - -* ) - error="$error -bad value for nprocd option" - ;; -esac - -case $nt in - -* ) - error="$error -bad value for nt option" - ;; -esac - -case $itree in - -* ) - error="$error -bad value for itree option" - ;; -esac -case $iam in - -* ) - error="$error -bad value for iam option" - ;; -esac -case $compatible in - N* | n*) - compatible=no - ;; - Y* | y*) - compatible=yes - ;; - unknown) - ;; - *) - error="$error -bad value for comp option" - ;; -esac -case $cpinput in - N* | n*) - cpinput=no - ;; - Y* | y*) - cpinput=yes - ;; - *) - error="$error -bad value for copy input option" - ;; -esac -case $cpresults in - N* | n*) - cpresults=no - ;; - Y* | y*) - cpresults=yes - ;; - *) - error="$error -bad value for copy results option" - ;; -esac - -# -# check for external file to run -# -if test -f $MARC_TOOLS/run_marc_check -then - . $MARC_TOOLS/run_marc_check -fi - -############################################################################## -# interact with the user to get the required information to run marc or # -# other marc system program # -############################################################################## - -deletelog=yes -if test $qid = background -a $verify = no -then -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $usersubname -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint -GPGPU option : $gpuids -Host file name : $host" > $jid.log -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -fi -echo \ -"Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" >> $jid.log -deletelog=no -fi -echo \ -" -Program name : $prog -Marc shared lib : $progdll -Version type : $mode -Job ID : $DIRJID/$jid -User subroutine name : $usersubname -User objects/libs : $objs -Restart file job ID : $rid -Substructure file ID : $sid -Post file job ID : $pid -Defaults file ID : $did -View Factor file ID : $vid -Save generated module: $prgsav -MPI library : $MPITYPE -DDM processes : $nprocdddmprint -Element loop threads : $nteprint -Solver processes : $nsolverprint -Solver threads : $ntsprint" -if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -fi -echo \ -"GPGPU option : $gpuids -Host file name : $host -Message passing type : $itree -Run job in queue : $qid -Run directory : $DIRJOB -Scratch directory : $DIRSCR -Memory limit in Mbyte: $memlimit" - - -case $qid in - s* | S* | l* | L* | v* | V* ) - echo \ -"Queue priority : $priority -Queue CPU limit : $cpu -Queue start time : $att" - ;; -# * ) -# echo \ -#" " -# ;; -esac - -if test "$modeoption" -then - error=$modeerror -fi - -if test "$error" -then - if test $verify = yes - then - $ECHO "$error - -Please correct or quit(correct,quit,): $ECHOTXT" - error= - read answer - case $answer in - q* | Q*) - answer=quit - ;; - *) - answer=correct - ;; - esac - else - $ECHO "$error - $ECHOTXT" - echo " " - if test "$deletelog" = no - then - $ECHO "$error - $ECHOTXT" >> $jid.log - echo " " >> $jid.log - fi - answer=quit - fi -else - if test $verify = yes - then - $ECHO " -Are these parameters correct (yes,no,quit,)? $ECHOTXT" - read answer - case $answer in - q* | Q*) - answer=quit - ;; - y* | Y*) - answer=yes - ;; - *) - answer=no - ;; - esac - else - answer=yes - fi -fi - -case $answer in - no | correct) - -############################################################################## -# prompt for each value # -############################################################################## - - $ECHO " -Program name ($prog)? $ECHOTXT" - read value - if test "$value" - then - prog=$value - fi - $ECHO "Job ID ($jid)? $ECHOTXT" - read value - if test "$value" - then - jid=`$BASENAME $value $dotdat` - DIRJID=`dirname $value` - case $DIRJID in - \/*) - ;; - *) - DIRJID=`pwd`/$DIRJID - ;; - esac - fi - $ECHO "User subroutine name ($usersubname)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - user= - ;; - *) - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user - basefile=`$BASENAME $value` - if test ${basefile##*.} = f - then - user=`dirname $value`/`$BASENAME $value .f` - usersubname=$user.f - elif test ${basefile##*.} = F - then - user=`dirname $value`/`$BASENAME $value .F` - usersubname=$user.F - elif test ${basefile##*.} = f90 - then - user=`dirname $value`/`$BASENAME $value .f90` - usersubname=$user.f90 - elif test ${basefile##*.} = F90 - then - user=`dirname $value`/`$BASENAME $value .F90` - usersubname=$user.F90 - fi - case $user in - \/*) - ;; - *) - user=`pwd`/$user - usersubname=`pwd`/$usersubname - ;; - esac - if test ! -f $usersubname - then - if test -f $usersubname.f - then - usersubname=$usersubname.f - elif test -f $usersubname.F - then - usersubname=$usersubname.F - elif test -f $usersubname.f90 - then - usersubname=$usersubname.f90 - elif test -f $usersubname.F90 - then - usersubname=$usersubname.F90 - fi - fi - ;; - esac - fi - $ECHO "User objects or libraries ($objs)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - objs= - ;; - *) - objs="$value" - ;; - esac - fi - $ECHO "Restart File Job ID ($rid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - rid= - ;; - *) - rid=`$BASENAME $value .t08` - DIRRID=`dirname $value` - case $DIRRID in - \/*) - ;; - *) - DIRRID=`pwd`/$DIRRID - ;; - esac - ;; - esac - fi - $ECHO "Substructure File ID ($sid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - sid= - ;; - *) - sid=$value - DIRSID=`dirname $value` - case $DIRSID in - \/*) - ;; - *) - DIRSID=`pwd`/$DIRSID - ;; - esac - ;; - esac - fi - $ECHO "Post File Job ID ($pid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - pid= - ;; - *) - pid=$value - DIRPID=`dirname $value` - case $DIRPID in - \/*) - ;; - *) - DIRPID=`pwd`/$DIRPID - ;; - esac - ;; - esac - fi - $ECHO "Defaults File ID ($did)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - did= - ;; - *) - did=`$BASENAME $value $dotdat` - DIRDID=`dirname $value` - case $DIRDID in - \/*) - ;; - *) - DIRDID=`pwd`/$DIRDID - ;; - esac - ;; - esac - fi - $ECHO "View Factor File ID ($vid)? $ECHOTXT" - read value - if test "$value" - then - case $value in - -*) - vid= - ;; - *) - vid=`$BASENAME $value .vfs` - DIRVID=`dirname $value` - case $DIRVID in - \/*) - ;; - *) - DIRVID=`pwd`/$DIRVID - ;; - esac - ;; - esac - fi - $ECHO "Save generated module ($prgsav)? $ECHOTXT" - read value - if test "$value" - then - prgsav=$value - fi - $ECHO "Run on tasks ($nprocdddm) tasks? $ECHOTXT" - read value - if test "$value" - then - nprocdddm=$value - nprocdddmprint=$value - fi - $ECHO "Run on ($nte) Element loop threads ? $ECHOTXT" - read value - if test "$value" - then - nte=$value - fi - $ECHO "Run on ($nsolver) solvers ? $ECHOTXT" - read value - if test "$value" - then - nsolver=$value - fi - $ECHO "Run on ($nts) Solver threads ? $ECHOTXT" - read value - if test "$value" - then - nts=$value - fi -# - if test $nprocdddm -gt 0 - then - nprocd=$nprocdddm - fi - if test $nsolver -gt 0 - then - if test $nsolver -gt $nprocd - then - nprocd=$nsolver - fi - fi -# Element loop threads. - if test $nte -eq -1 - then - nte=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nte -lt 0 - then - nte=0 - fi - nteprint=$nte -# Copy from ddm - if test $nprocdddm -gt 1 - then - nteprint=$nprocdddm - fi -# override with -nthread_elem option - if test $nte -ne 0 - then - nteprint=$nte - fi -# check for minimum 1 threads per processes for DDM - if test $nprocdddm -ne 0 - then - if test $nteprint -lt $nprocdddm - then - nteprint=$nprocdddm - fi - fi - nte=$nteprint -# Solver threads. - if test $nts -eq -1 - then - nts=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nts -lt 0 - then - nts=0 - fi - ntsprint=$nts -# Copy from ddm - if test $nprocdddm -gt 1 - then - ntsprint=$nprocdddm - fi -# override with -nthread_solver option - if test $nts -ne 0 - then - ntsprint=$nts - fi -# check for minimum 1 threads per solver process. - if test $nsolver -lt $nprocdddm - then - if test $ntsprint -lt $nsolver - then - ntsprint=$nsolver - fi - else - if test $ntsprint -lt $nprocdddm - then - ntsprint=$nprocdddm - fi - fi - if test $ntsprint -eq 1 - then - set ntsprint=0 - fi - nts=$ntsprint -# Update print variable for -nsolver option - nsolverprint=$nsolver - if test $nsolver -eq 0 - then - nsolverprint= - fi - $ECHO "GPGPU id option ($gpuids)? $ECHOTXT" - read value - if test "$value" - then - gpuids=$value - fi - if test "$gpuids" = "" ; then - gpuoption= - else - gpuoption="-gp $gpuids" - fi - if test "$gpuids" = "" ; then - export LD_LIBRARY_PATH=$CUDALIB1:$LD_LIBRARY_PATH - else - MARCCUDALIBS=$MARCCUDALIBS2 - export LD_LIBRARY_PATH=$CUDALIB2:$LD_LIBRARY_PATH - fi - if test $MPITYPE = hpmpi -a "$ARCHITECTURE" = "linux_amd64" - then - export MPIHPSPECIAL="$MPIHPSPECIAL -e LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - fi -# - if test $nprocd -gt 1 - then - $ECHO "Message passing type ($itree)? $ECHOTXT" - read value - if test "$value" - then - itree=$value - fi - $ECHO "Host file name ($host)? $ECHOTXT" - read value - if test "$value" - then - host=$value - fi - if test $nprocdddm -gt 1 - then - $ECHO "Single input file? $ECHOTXT" - read value - case $value in - y* | Y*) - icreated=1 - nprocdarg=-nprocds - ;; - esac - $ECHO "Compatible machines for DDM ($compatible)? $ECHOTXT" - read value - if test "$value" - then - compatible=$value - fi - $ECHO "Copy input files to remote hosts ($cpinput)? $ECHOTXT" - read value - if test "$value" - then - cpinput=$value - fi - $ECHO "Copy post files from remote hosts ($cpresults)? $ECHOTXT" - read value - if test "$value" - then - cpresults=$value - fi - fi - fi - $ECHO "Run the job in the queue ($qid)? $ECHOTXT" - read value - if test "$value" - then - qid=$value - fi - case $qid in - s* | S* | l* | L* | v* | V* ) - $ECHO "Queue priority ($priority)? $ECHOTXT" - read value - if test "$value" - then - priority=$value - fi - $ECHO "Job starts at ($att)? $ECHOTXT" - read value - if test "$value" - then - att=$value - fi - $ECHO "Queue CPU limit ($cpu)? $ECHOTXT" - read value - if test "$value" - then - cpu=$value - fi - ;; - * ) - ;; - esac - $ECHO "Run directory ($DIRJOB)? $ECHOTXT" - read value - if test "$value" - then - DIRJOB=$value - DIRSCR=$DIRJOB - fi - $ECHO "Scratch directory ($DIRSCR)? $ECHOTXT" - read value - if test "$value" - then - DIRSCR=$value - fi - ;; - quit) - exit 1 - ;; - *) - break - ;; - -esac - - if test $nt -eq -1 - then - nt=${MARC_NUMBER_OF_THREADS:-0} - fi - if test $nt -lt 0 - then - nt=0 - fi - -done -# -if test $nt -eq 0 -then - ntarg= -fi -if test $nt -eq 0 -then - ntprint= -fi -if test $nt -eq 0 -then - nt= -fi - -if test $nte -eq 0 -then - ntearg= -fi -if test $nte -eq 0 -then - nteprint= -fi -if test $nte -eq 0 -then - nte= -fi - -if test $nts -eq 0 -then - ntsarg= -fi -if test $nts -eq 0 -then - ntsprint= -fi -if test $nts -eq 0 -then - nts= -fi -# -if test "$dllrun" -gt 0; then - exefile=exe_marc - prog=exe_marc - program=$exefile - bd=$MARC_BIN/ - if test "$user"; then - . $MARC_TOOLS/make_marc_user_dll $DIRJOB $user - user= - pathdll=yes - if test $prgsav = no; then - rmdll=yes - fi - if test $prgsav = yes; then - cpdll=yes - rmdll=yes - fi - fi - - if test "$pathdll"; then -# -# reset share lib path -# - if test $MACHINENAME = "HP" - then - SHLIB_PATH=$DIRJOB:$SHLIB_PATH - export SHLIB_PATH - fi - if test $MACHINENAME = "IBM" - then - LIBPATH=$DIRJOB:$LIBPATH - export LIBPATH - fi -# - LD_LIBRARY_PATH=$DIRJOB:$LD_LIBRARY_PATH - LD_LIBRARY64_PATH=$DIRJOB:$LD_LIBRARY64_PATH - LD_LIBRARYN32_PATH=$DIRJOB:$LD_LIBRARYN32_PATH - export LD_LIBRARY_PATH - export LD_LIBRARY64_PATH - export LD_LIBRARYN32_PATH - fi -fi -# end of dllrun>0 - - -if test $program = $exefile -o $program = $prog.marc -then - -# delete the old .log file unless we run in the background -if test "$deletelog" = yes -then - if test "$jid" - then - /bin/rm $jid.log 2>/dev/null - fi -else - echo - echo running the job in the background, see $jid.log - echo -fi - -# -# check if this is an autoforge or rezoning or radiation job -# -if test $nprocd -eq 1 -a "$jid" - -then - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^autoforge"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^rezoning"` - if test "$line" - then - autoforge=1 - fi - line=`$AWK '/^[eE][nN][dD]/ {exit} ; {print}' $DIRJID/${jid}$dotdat | grep -i "^radiation"` - if test "$line" - then - autoforge=1 - fi -fi -# -# check that jobname for restarted run is not the same -# as restart file basename -# -if test "$rid" -then - if test "$jid" = "$rid" - then - echo " " - echo "ERROR: job name of current run is the same as job name" - echo " of the restarted job" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "ERROR: job name of current run is the same as job name" >> $jid.log - echo " of the restarted job" >> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi -fi - -# -# user objects/libraries used -# - - if test "$objs" - then - program="$DIRJOB/$jid.marc" - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# user subroutine used -# - - if test "$user" - then -# program=$user.marc - program=$DIRJOB/`$BASENAME $user .f`.marc - case $program in - \/* | \.\/*) - bd= - ;; - *) - bd=`pwd`/ - ;; - esac - link=yes - fi - -# -# Special case for IBM using POE but not an SP machine -# in this case we always need a host file, also for serial jobs. -# -if test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP -then - MP_HOSTFILE=${jid}.host - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $nprocd -gt 1 - then - numdom=$nprocd - while test $numdom -gt 0 - do - hostname -s >> $MP_HOSTFILE - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - else - hostname -s > $MP_HOSTFILE - fi -fi -# -# check ssh for all hosts in host file -# -if test $nprocd -gt 1 -then -if test $MPITYPE = "intelmpi" -a "$INTELMPI_VERSION" = "HYDRA" - then -# get host list - if test "$host" - then - line=`grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' | uniq` -# count failing hosts - counter=0 - for i in $line - do - $RSH -o BatchMode=yes -o ConnectTimeout=10 $i uname -n - status=$? - if [[ $status != 0 ]] ; then - counter=$((counter+1)) - if [ "$counter" = "1" ]; then - echo " " - echo " error - connection test failed... " - echo " " - fi - echo " " - echo " connection test with ssh failed on host $i" - echo " check the following command: ssh $i uname -n " - echo " " - fi - done -# echo error message and quit - if test $counter -ne 0 - then - echo " " - echo " A parallel job using IntelMPI cannot be started. " - echo " The ssh command must be working correctly between " - echo " the computers used in the analysis. Furthermore, " - echo " it must be set up such that it does not prompt the " - echo " user for a password. " - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo " A parallel job using IntelMPI cannot be started. ">> $jid.log - echo " The ssh command must be working correctly between ">> $jid.log - echo " the computers used in the analysis. Furthermore, ">> $jid.log - echo " it must be set up such that it does not prompt the ">> $jid.log - echo " user for a password. ">> $jid.log - echo " " >> $jid.log - echo " Exit number 8" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi -fi -fi -# -# check correctness of host file; fix for user sub -# - if test $nprocd -gt 1 - then - -# construct the path name to the executable (execpath) - execpath=$MARC_BIN/$exefile - usersub=0 - if test $program = $prog.marc - then - execpath=$prog.marc - usersub=1 - fi - if test "$objs" - then - execpath="$DIRJOB/$jid.marc" - usersub=1 - fi - if test "$user" - then - execpath=$DIRJOB/`$BASENAME $user .f`.marc - usersub=1 - fi - export execpath - execname=`$BASENAME $execpath` - - if test "$host" - then - userhost=$host - case $userhost in - \/* | \.\/*) - ;; - *) - userhost=`pwd`/$userhost - ;; - esac - -# check that the number of processes specified in the hostfile is -# equal to nprocd specified by -nprocd. - numproc=`grep -v '^#' $host | $AWK -v sum=0 '{sum=sum+$2}; END {print sum}'` - if test $nprocd -ne $numproc - then - echo " " - echo "error, the number of processes specified in the host file" - echo "must be equal to the number of processes given by -nprocd/-nsolver" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, the number of processes specified in the host file" >> $jid.log - echo "must be equal to the number of processes given by -nprocd/-nsolver" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - -# check for Myrinet that the number of processes per host is -# less than number of available user ports, 5 -# .gmpi directory must exist in user's home directory -# and must have write permission from remote hosts - if test $MPITYPE = "myrinet" - then - numproc=`grep -v '^#' $host | $AWK -v sum=1 '{if( $2 > 5) sum=6}; END {print sum}'` - if test $numproc -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes specified " - echo "in the hostfile must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes specified " >> $jid.log - echo "in the hostfile must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - if test ! -d ~/.gmpi - then - echo " " - echo "error, for Myrinet a .gmpi directory must exist " - echo "under the user's home directory" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a .gmpi directory must exist " >> $jid.log - echo "under the user's home directory" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - homedir=`echo ~` - for i in `grep -v '^#' $host | $AWK '{if (NF > 0) print $1}'` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - $RSH $i /bin/touch $homedir/.gmpi/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - echo " " - echo "error, for Myrinet a shared .gmpi directory must exist " - echo "under the user's home directory " - echo "with remote write permission" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet a shared .gmpi directory must exist " >> $jid.log - echo "under the user's home directory " >> $jid.log - echo "with remote write permission" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - else - /bin/rm tmp.$$ - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - fi - fi - done - fi - fi - -# construct the host file $jid.host which is used by mpirun -# skip lines starting with # and only consider lines with more than -# one word in them. Note that the hostfile given to this script -# has two columns: the host name and the number of shared processes -# to run on this host. mpirun wants the number of _other_ -# processes to run in addition to the one being run on the machine -# on which the job is started. hence the $2-1 for fnr == 1. - if test -f $jid.host - then - /bin/rm $jid.host 2> /dev/null - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then -# HPMPI or HP hardware MPI - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ - -v mpihpspecial="$MPIHPSPECIAL" \ -'{if ( NF > 0) {\ - fnr++ ; \ - printf("-h %s -np %s",$1,$2); \ - printf(" %s",mpihpspecial); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF >= 3 ) printf(" -e MPI_WORKDIR=%s", $3);\ - if ( NF >= 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) \ - }\ - }' > $jid.host -# end HPMPI or HP hardware MPI - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then -# IBM using hardware MPI (POE) - MP_HOSTFILE=$jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.host -# end IBM using hardware MPI (POE) -# for Intel MPI, need to create a machinefile for DMP - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then -# Intel MPI - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - /bin/cp $host $jid.host - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Intel MPI for DMP -# for Solaris HPC 7.1, need to create a machinefile for DMP - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then -# Solaris HPC 7.1 - if test -f $jid.mfile - then - /bin/rm $jid.mfile 2> /dev/null - fi - grep -v '^#' $host | $AWK '{host=$1;num=$2;for (i=1;i<=num;i++) print host}' > $jid.mfile -# end Solaris HPC 7.1 for DMP -# for Myrinet, construct a configuration file in ~/.gmpi -# this must be readable by each process -# format is (hostname) (port number) for each process - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - grep -v '^#' $host | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ -{if ( NF > 0 ) \ - for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc]); \ -}' >> ~/.gmpi/$jid.host - else -# this is for mpich-1.2.5 and later, using the -pg option -# format: host nproc executable user arguments -# the arguments are added later - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub -v user=`whoami` \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s %s\n",path,user);\ - if ( NF == 3 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s %s\n",path,user) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s %s\n",$3,en,user); else printf(" %s/bin/%s %s\n",$4,en,user) \ - }\ - }' > $jid.host - fi -# end Myrinet - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then -# Compaq MPI via Memory Channel - grep -v '^#' $host | $AWK '{if (NF > 0) print $1}' > $jid.host -# end Compaq MPI - else -# MPICH - grep -v '^#' $host | $AWK -v path=$execpath -v en=$execname -v us=$usersub \ -'{if ( NF > 0) {\ - fnr++ ; \ - if ( fnr == 1 ) printf("%s %d",$1,$2-1); \ - else printf("%s %s",$1,$2); \ - if ( NF == 2 ) printf(" %s\n",path);\ - if ( NF == 3 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s\n",path) ;\ - if ( NF == 4 ) if (us) printf(" %s/%s\n",$3,en); else printf(" %s/bin/%s\n",$4,en) \ - }\ - }' > $jid.host - fi -# define the variable host and host_filt -# host_filt is used for loops over hosts -# for Myrinet we need to use a filtered variant of userhost -# for others we can use $host - if test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - host=~/.gmpi/$jid.host - host_filt=$jid.host_tMp - grep -v '^#' $userhost | $AWK '{if (NF > 0) print $1}' > $host_filt - else - host=$jid.host - host_filt=$host - fi - else - host=$jid.host - host_filt=$host - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - host_filt=$jid.mfile - fi - fi -# figure out if the machines in the hostfile are nfs mounted -# or distributed and set the variable "dirstatus" accordingly. -# only perform the check if user subroutine is used -# or a user subroutine executable is used - - numfield=1 - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - numfield=2 - fi - DIR1=$DIRJOB - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - counter=0 - echo " " - echo "checking if local or shared directories for host" - if test "$deletelog" = no - then - echo "checking if local or shared directories for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - dirstatus[$counter]="shared" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - $RSH $i /bin/touch $DIR1/$jid.$$ 2> tmp.$$ - if test -s tmp.$$ - then - dirstatus[$counter]="local" - /bin/rm tmp.$$ - else - if test ! -f $jid.$$ - then - dirstatus[$counter]="local" - $RSH $i /bin/rm $DIR1/$jid.$$ - else - /bin/rm $jid.$$ - fi - fi - if test -f tmp.$$ - then - /bin/rm tmp.$$ - fi - if test -f $jid.$$ - then - /bin/rm $jid.$$ - fi - echo " ${dirstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${dirstatus[$counter]}" >> $jid.log - fi - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - fi - -# figure out if this is a compatible set of machines -# unless explicitly specified with flag -comp -# only perform the check if user subroutine is used -# or a user subroutine executable is used -# Myrinet does not support heterogeneous - if test $program = $prog.marc -o -n "$user" -o -n "$objs" - then - if test $compatible = "unknown" - then - thisname=$ARCH - compatible=yes - counter=0 - echo "checking if machines are compatible for host" - if test "$deletelog" = no - then - echo "checking if machines are compatible for host" >> $jid.log - fi - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]="yes" - $ECHO " $i $ECHOTXT" - if test "$deletelog" = no - then - $ECHO " $i $ECHOTXT" >> $jid.log - fi - othername=`$RSH $i uname -a | cut -f 1 -d " "` - if test $thisname != $othername - then - compatible=no - compstatus[$counter]="no" - fi - fi - echo " ${compstatus[$counter]}" - if test "$deletelog" = no - then - echo " ${compstatus[$counter]}" >> $jid.log - fi - done - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - fi - else - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - compstatus[$counter]=$compatible - fi - done - if test $compatible = "no" - then - echo "all machines assumed incompatible" - if test "$deletelog" = no - then - echo "all machines assumed incompatible" >> $jid.log - fi - else - echo "all machines compatible" - if test "$deletelog" = no - then - echo "all machines compatible" >> $jid.log - fi - fi - fi -# error out if user objects or libraries are used on incompatible machines - if test "$compatible" = "no" -a -n "$objs" - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" - if test "$deletelog" = no - then - echo "User object/libraries cannot be used in a parallel job on incompatible machines" >> $jid.log - fi - exit 1 - fi -# modify new host file if NFS mounted heterogeneous machine - doit= - if test $program = $prog.marc - then - doit=yes - fi - if test "$user" - then - doit=yes - fi - if test "$doit" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - $AWK -v hst=$i '{fnr++ ; \ -if ($1 ~ hst) {if ( fnr == 1 ) printf("%s\n",$0); else \ -printf("%s %s %s_%s\n",$1,$2,$3,$1) } else print}' $jid.host > $jid.host{$$} - /bin/mv $jid.host{$$} $jid.host - host=$jid.host - fi - fi - done - fi - fi # if test $program = $prog.marc -o $user -o $obj - - else # if test $host - # assume shared memory machine if no hostfile given and - # MPITYPE is set to mpich or Myrinet - # check for Myrinet that the total number of processes is - # less than number of available user ports, 5 - if test $MPITYPE = "mpich" -o $MPITYPE = "scali" - then - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - host=$jid.host - elif test $MPITYPE = "myrinet" - then - if test $nprocd -gt 5 - then - echo " " - echo "error, for Myrinet the number of processes " - echo "must not exceed 5 for a hostname" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error, for Myrinet the number of processes " >> $jid.log - echo "must not exceed 5 for a hostname" >> $jid.log - echo " " >> $jid.log - fi - exit 1 - fi - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - echo $nprocd > ~/.gmpi/$jid.host - echo `hostname` $nprocd | $AWK \ -'BEGIN {iport[0] = 2; \ - iport[1] = 4; \ - iport[2] = 5; \ - iport[3] = 6; \ - iport[4] = 7 \ - } \ - {for(iproc = 0; iproc < $2; iproc++) printf("%s %d\n",$1,iport[iproc])} \ -' >> ~/.gmpi/$jid.host - host=~/.gmpi/$jid.host - else - numproc=`echo $nprocd | $AWK '{sum=$1-1}; {print sum}'` - echo `hostname` $numproc $execpath > $jid.host - - fi - fi # if test myrinet - - fi # if test $host - - fi # if test $nprocd -gt 1 - -fi # if test $program = $exefile -o $program = $prog.marc - -############################################################################## -# construct run stream (Marc only) # -############################################################################## - -# set maximum message length for ddm to a large number -# for vendor provided mpi -if test $itree -eq 0 -a $MPITYPE = hardware -then - itree=100000000 - if test $MACHINENAME = SGI - then - itree=100000001 - fi -fi -if test $itree -eq 0 -a $MPITYPE = hpmpi -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = myrinet -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = nec -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = scali -then - itree=100000000 -fi -if test $itree -eq 0 -a $MPITYPE = intelmpi -then - itree=100000000 -fi -if test $nprocdddm -lt 2 -then - nprocdarg= -else - nprocdarg="$nprocdarg $nprocdddm" -fi -if test $nsolver -eq 0 -then - nsolverarg= -else - nsolverarg="$nsolverarg $nsolver" -fi -if test $nprocdddm -lt 2 -a $nsolver -eq 0 -then -nprocd=0 -fi -if test $nprocd -gt 0 -then - if test "$host" - then - if test -z "$RUN_JOB2" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - if test $MPITYPE = hpmpi -o $MACHINENAME = HP -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $host -- -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = IBM -a $MPITYPE = hardware -a "$MACHINETYPE" = NONSP - then - RUN_JOB="$RUN_JOB2 $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MPITYPE = "myrinet" - then - if test $MPIVERSION = "MPICH-GM1.2.1..7" - then - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB_TMP="$RUN_JOB2 $host $bd$program" - RUN_JOB=" -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - elif test $MACHINENAME = DEC -a $MPITYPE = hardware - then - RUN_JOB="$RUN_JOB2 $nprocd -hf $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - elif test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - numhost=`uniq $jid.mfile | wc -l` - if test "$INTELMPI_VERSION" = "HYDRA" - then - RUN_JOB_TMP="$RUN_JOB2 -configfile $jid.cfile" - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n $numhost -r $RSH -f $jid.mfile - RUN_JOB_TMP="$RUN_JOB2 $jid.cfile" - fi - -# intelmpi uses configfile. format: -# -host host1 -n n1 executable marcargs -# one such line per host -# collect the marcargs in RUN_JOB and construct the config file later -# collect the run stream in RUN_JOB_TMP - RUN_JOB="-jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - - - elif test $MACHINENAME = "SUN" -a $MPITYPE = "hardware" - then - RUN_JOB="$RUN_JOB2 $jid.mfile -n $nprocd $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB2 $host $bd$program -jid $jid -dirjid $DIRJID \ -$nprocdarg \ -$nsolverarg \ --maxnum $MAXNUM -itree $itree \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test "$userhost" - then - RUN_JOB="$RUN_JOB -mhost $userhost" - fi - if test $MPITYPE = "scali" - then -# set default working directory to /tmp to allow -# different directory names - SCAMPI_WORKING_DIRECTORY=/tmp - export SCAMPI_WORKING_DIRECTORY - fi - else - if test -z "$RUN_JOB1" - then - echo " " - echo "error: parallel job attempted on non-parallel version," - echo " or, if parallel version is installed, the include " - echo " file is probably corrupted" - echo " " - if test "$deletelog" = no - then - echo " " >> $jid.log - echo "error: parallel job attempted on non-parallel version," >> $jid.log - echo " or, if parallel version is installed, the include " >> $jid.log - echo " file is probably corrupted" >> $jid.log - echo " " >> $jid.log - fi - exit - fi - RUNNPROCD=$nprocd - if test $MACHINENAME = "IBM" -a $MPITYPE = "hardware" - then - RUNNPROCD= - MP_PROCS=$nprocd - export MP_PROCS - fi - if test $MPITYPE = "myrinet" - then - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - echo " " > /dev/null - else - export I_MPI_JOB_CONTEXT=$$ - mpdboot -n 1 -f $jid.hosts - fi - RUN_JOB="$RUN_JOB1 $RUNNPROCD $bd$program -jid $jid -dirjid $DIRJID \ - $nprocdarg \ - $nsolverarg \ - -maxnum $MAXNUM -itree $itree \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi - fi -else - if test $ndcoup -gt 0 - then - RUN_JOB="$RUN_JOB0 $BINDIR/exe_auto $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ - $ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - else -# this is for a serial job without auto restart: - RUN_JOB="$RUN_JOB0 $bd$program -jid $jid -dirjid $DIRJID \ --maxnum $MAXNUM \ -$ntearg $nte $ntsarg $nts $gpuoption -dirjob $DIRJOB " - fi -fi -if test "$rid" -then - RUN_JOB="$RUN_JOB -rid $rid -dirrid $DIRRID" -fi -if test "$pid" -then - RUN_JOB="$RUN_JOB -pid $pid -dirpid $DIRPID" -fi -if test "$sid" -then - RUN_JOB="$RUN_JOB -sid $sid -dirsid $DIRSID" -fi -if test "$did" -then - RUN_JOB="$RUN_JOB -def $did -dirdid $DIRDID" -fi -if test "$vid" -then - RUN_JOB="$RUN_JOB -vf $vid -dirvid $DIRVID" -fi -if test $ndcoup -gt 0 -then - RUN_JOB="$RUN_JOB -dcoup $ndcoup " -fi -if test $ndytran -gt 0 -then - RUN_JOB="$RUN_JOB -dytran $ndytran " -fi -if test $mesh -gt 0 -then - RUN_JOB="$RUN_JOB -me $mesh " -fi -if test $noutcore -gt 0 -then - RUN_JOB="$RUN_JOB -outcore $noutcore " -fi -if test "$dllrun" -gt 0 -then - RUN_JOB="$RUN_JOB -dll $dllrun " -fi -if test "$trkrun" -gt 0 -then - RUN_JOB="$RUN_JOB -trk $trkrun " -fi -if test "$iam" -then - RUN_JOB="$RUN_JOB -iam $iam " -fi -if test "$justlist" -then - RUN_JOB="$RUN_JOB -list 1 " -fi -if test "$feature" -then - RUN_JOB="$RUN_JOB -feature $feature " -fi -if test "$memlimit" -ne 0 -then - RUN_JOB="$RUN_JOB -ml $memlimit " -fi -if test "$cpinput" -then - RUN_JOB="$RUN_JOB -ci $cpinput " -fi -if test "$cpresults" -then - RUN_JOB="$RUN_JOB -cr $cpresults " -fi -if test "$DIRSCR" != "$DIRJOB" -then - RUN_JOB="$RUN_JOB -dirscr $DIRSCR" -else - DIRSCR=$DIRJOB -fi -if test "$makebdf" -then - RUN_JOB="$RUN_JOB -bdf $makebdf " -fi -if test $MPITYPE = "myrinet" -a "$host" -a "$MPIVERSION" != "MPICH-GM1.2.1..7" -then - # append $RUN_JOB to all lines of the host file - # and set RUN_JOB - $AWK -v args="$RUN_JOB" '{print $0,args}' $host > $host.$$ - /bin/mv $host.$$ $host - RUN_JOB=$RUN_JOB_TMP -fi -if test $MPITYPE = "intelmpi" -a "$host" -then - # construct config file, append $RUN_JOB to all lines of the config file - # and set RUN_JOB - if test "$INTELMPI_VERSION" = "HYDRA" - then - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf(" -host %s",$1); \ - printf(" -n %s",$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - else - grep -v '^#' $host | $AWK -v args="$RUN_JOB" -v path=$execpath -v en=$execname -v us=$usersub \ - '{if ( NF > 0) {\ - printf("-host %s -n %s",$1,$2); \ - if ( NF == 2 ) printf(" %s",path);\ - if ( NF >= 3 ) printf(" -wdir %s ",$3); \ - if ( NF >= 3 ) if (us) printf(" %s/%s",$3,en); else printf(" %s",path); \ - printf(" %s\n",args); \ - }\ - }' > $jid.cfile - fi - RUN_JOB=$RUN_JOB_TMP -fi -echo " " -echo "Final run stream value" -echo " RUNJOB="$RUN_JOB -if test "$deletelog" = no -then -echo " " >> $jid.log -echo "Final run stream value" >> $jid.log -echo " RUNJOB="$RUN_JOB >> $jid.log -fi - - -############################################################################## -# run marc using valgrind # -############################################################################## -#RUN_JOB="valgrind $RUN_JOB" -#RUN_JOB="valgrind --read-var-info=yes --gen-suppressions=yes $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=all -v $RUN_JOB" -#RUN_JOB="valgrind --gen-suppressions=yes --error-limit=no $RUN_JOB" -############################################################################## - - -############################################################################## -# run the requested program in a queue # -############################################################################## - -if test "$deletelog" = yes -then - echo - date -else - echo >> $jid.log - date >> $jid.log -fi -if [ $qid = short -o $qid = long -o $qid = verylong -o $qid = at ] -then - -/bin/rm -f $jid.runmarcscript - - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - userobj=$DIRJOB/`$BASENAME $user .f`.o - basefile=`$BASENAME $usersubname` - if test ${basefile##*.} = f - then - usersub=$DIRJOB/`$BASENAME $user .f`.F - ln -sf "$user.f" "$usersub" - else - usersub=$usersubname - fi - - fi - cat > $jid.runmarcscript << END4 - if test "$user" - then - if test ${basefile##*.} = f - then - ln -sf "$user.f" "$usersub" - fi - if test $MACHINENAME = "CRAY" - then - $FORTRAN $usersub || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $FORTRAN $usersub -o $userobj || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - if test ${basefile##*.} = f - then - /bin/rm -f "$usersub" - fi - fi - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - $SOLVERLIBS \ - $MARCCUDALIBS \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } -END4 -else - prgsav=yes -fi -/bin/rm $userobj 2>/dev/null - -# -# run marc -# - -cat >> $jid.runmarcscript << END5 - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# first remove all .out files and incremental restart files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - /bin/rm $DIRJOB/$numdom${jid}_i_*.t08 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null - /bin/rm $DIRJOB/${jid}_i_*.t08 2>/dev/null -fi - -if test $nprocdddm -gt 1 -then - $RUN_JOB 2>>$jid.log -else - $RUN_JOB 2>>$jid.log -fi - -if test $dllrun -eq 0; then - if test $prgsav = no - then - /bin/rm -f $bd$program 2>/dev/null - fi -else - if test $cpdll = yes; then - filename=`basename $usersubname .f` - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes - then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test \$numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - numdom=\`echo \$numdom | $AWK '{sum=\$1-1}; {print sum}'\` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null -fi -END5 - - -# Submit to marc batch queue -# -if [ $qid = at ] -then -QUENAME=at -SUBMCMD= -else -# -# Submit to qsub queue -# -QUENAME=qsub -SUBMCMD="-q $qid -o /dev/null -e $jid.batch_err_log -x -r $jid" -if test "$priority" -then - SUBMCMD=$SUBMCMD" -p $priority" -fi -if test "$att" -then - SUBMCMD=$SUBMCMD" -a $att" -fi -if test "$cpu" -then - SUBMCMD=$SUBMCMD" -lt $cpu" -fi - -fi -echo $QUENAME $SUBMCMD -#cat $jid.runmarcscript -$QUENAME $SUBMCMD < $jid.runmarcscript - -/bin/rm -f $jid.runmarcscript - -############################################################################## -# run the requested program in the background # -############################################################################## - -else -if test $qid = background -then - -# -# first remove all old .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi -# -# compile user subroutine if present -# -( -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user.f $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user.f on host $i" - echo " $PRODUCT Exit number 3" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser.f 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user.f on host `hostname`" - fi - userobj=$DIRJOB/`$BASENAME $user .f`.o - basefile=`$BASENAME $usersubname` - if test ${basefile##*.} = f - then - usersub=$DIRJOB/`$BASENAME $user .f`.F - ln -sf "$user.f" "$usersub" - else - usersub=$usersubname - fi - if test $MACHINENAME = "CRAY" - then - $FORTRAN $usersub || \ - { - echo "$0: compile failed for $user.f" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $FORTRAN $usersub -o $userobj || \ - { - echo "$0: compile failed for $user.f" - echo " $PRODUCT Exit number 3" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - if test ${basefile##*.} = f - then - /bin/rm -f "$usersub" - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null - -# -# run marc - -# - -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - - -$RUN_JOB & - -marcpid=$! -echo $marcpid > $DIRJOB/$jid.pid -wait $marcpid - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - fi - fi - fi -fi - - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi - fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=`basename $usersubname .f` - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi -) 1>>$jid.log 2>&1 & - - -############################################################################## -# run the requested program in the foreground # -############################################################################## - -else - -# -# compile user subroutine if present -# -if test "$link" -then - if test -z "$FCOMPROOT"; then - echo "$0: No compiler available" - echo - echo " $PRODUCT Exit number 3" - exit 1 - fi - echo - echo "Using compiler from: $FCOMPROOT" - echo - if test "$user" - then - # compile and link on other hosts in $host if compstatus=no - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${compstatus[$counter]} = "no" - then - DIR1=$DIRJOB - DIR2=$DIR - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - marcdir=`echo $line | $AWK '{print $4}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - if test -n "$marcdir" - then - DIR2=$marcdir - fi - # first copy over the user sub if local directories - if test ${dirstatus[$counter]} = "local" - then - $RCP $user.f $i:$DIR1/ - fi - # do the compilation on the other machine - if test ${dirstatus[$counter]} = "shared" - then - hname=_$ibase - else - hname= - fi - remoteprog=$DIR1/${execname}$hname - remoteuser=$DIR1/`$BASENAME $user` - $RSH $i /bin/rm $remoteprog 2> /dev/null - echo - $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog - # check if successful, the new executable should be there - line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` - if test "$line" - then - echo compilation and linking successful on host $i - else - echo "$0: compile failed for $user.f on host $i" - exit 1 - fi - # remove the user subroutine on remote machine - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $remoteuser.f 2> /dev/null - fi - fi - fi - done - fi - fi - if test "$userhost" - then - echo - echo "Compiling and linking user subroutine $user.f on host `hostname`" - fi - userobj=$DIRJOB/`$BASENAME $user .f`.o - basefile=`$BASENAME $usersubname` - if test ${basefile##*.} = f - then - usersub=$DIRJOB/`$BASENAME $user .f`.F - ln -sf "$user.f" "$usersub" - else - usersub=$usersubname - fi - if test $MACHINENAME = "CRAY" - then - $FORTRAN $usersub || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - else - $FORTRAN $usersub -o $userobj || \ - { - echo "$0: compile failed for $user.f" - exit 1 - } - /bin/rm $program 2>/dev/null - fi - if test ${basefile##*.} = f - then - /bin/rm -f "$usersub" - fi - fi # if test $user - - - $LOAD $bd${program} $MARC_LIB/main.o \ - $MARC_LIB/blkdta.o $MARC_LIB/comm?.o \ - ${userobj-} \ - $objs \ - $MARC_LIB/srclib.a \ - $MNFLIBS \ - $MDUSER \ - ${MUMPSSOLVERLIBS} \ - $MDSRCLIB \ - $MARC_LIB/mcvfit.a \ - $STUBS \ - ${SOLVERLIBS} \ - ${MARCCUDALIBS} \ - $TKLIBS \ - $MRCLIBS \ - $METISLIBS \ - $OPENSSL_LIB \ - $SYSLIBS \ - $SFLIB \ - $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 - } - # copy user subroutine executable for hosts using local working dir - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - if test ${dirstatus[$counter]} = "local" -a ${compstatus[$counter]} = "yes" - then - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - echo "Copying executable to host ${i}" - $RCP $program ${i}:${DIR1}/ - fi - fi - done - fi - fi -else # if test $link - prgsav=yes -fi # if test $link -/bin/rm $userobj 2>/dev/null - -# done if no job id given -if test -z "$jid" -then - echo - echo only compilation requested - echo - exit -fi -# -# run marc -# -# Define share library path based on platforms -# This is required for using the Patran Mesher -if test $MACHINENAME = "IBM" -then - LIBPATH=$MARC_LIB:$MARC_LIB_SHARED:$LIBPATH - export LIBPATH -fi -# first remove all .out files -# the ones for ddm are removed in the code -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRJOB/$numdom$jid.out 2>/dev/null - /bin/rm $DIRJOB/$numdom$jid.log 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done -else - /bin/rm $DIRJOB/$jid.out 2>/dev/null -fi - -# for DDM with ARC support - -if test $ddm_arc -gt 0; then - RUN_JOB="$MESHERDIR/sf_exeddm $RUN_JOB -ddm $ddm_arc " -fi - -$RUN_JOB - -if test $nprocd -gt 1 -then - if test $MACHINENAME = "LINUX" -a $MPITYPE = "intelmpi" - then - if test "$INTELMPI_VERSION" = "HYDRA" - then - if test "$host" - then - /bin/rm $jid.mfile 2> /dev/null - /bin/rm $jid.hosts 2> /dev/null - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.cfile 2> /dev/null - else - echo " " > /dev/null - fi - else - if test "$host" - then - mpdcleanup -a -f $jid.mfile - /bin/rm $jid.host 2> /dev/null - /bin/rm $jid.mfile 2> /dev/null - else - mpdcleanup -a -f $jid.hosts - /bin/rm $jid.hosts 2> /dev/null - fi - fi - fi -fi - -if test $dllrun -eq 0; then -if test $prgsav = no -then - /bin/rm -f $bd$program 2>/dev/null - # for network run, remove executable on remote machines - # and executables with modified name - if test $nprocd -gt 1 - then - if test "$userhost" - then - counter=0 - if test -f "$host_filt" - then - for i in `$AWK -v n=$numfield '{print $n}' $host_filt` - do - ibase=${i%%.*} - if test $ibase != $thishost - then - counter=$((counter+1)) - DIR1=$DIRJOB - line=`grep -v '^#' $userhost | grep "^$ibase "` - workdir=`echo $line | $AWK '{print $3}'` - if test -n "$workdir" - then - DIR1=$workdir - fi - # if an incompatible host uses shared directory, - # then the root machine deletes the executable - if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" - then - hname=_$ibase - /bin/rm ${execname}$hname - fi - # if local directory used, the remote machine - # deletes the executable - if test ${dirstatus[$counter]} = "local" - then - $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null - fi - fi - done - fi - fi - fi -fi -else -#dllrun >0 - if test $cpdll = yes; then - filename=`basename $usersubname .f` - /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null - fi - if test $rmdll = yes;then - /bin/rm -f $DIRJOB/$marcdll 2>/dev/null - fi -fi - -if test $nprocdddm -gt 1 -then - numdom=$nprocdddm - while test $numdom -gt 0 - do - /bin/rm $DIRSCR/$numdom$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t74 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t75 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t76 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t77 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t78 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t79 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t84 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t85 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t86 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t87 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t88 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.t90 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sle 2>/dev/null - /bin/rm $DIRSCR/$numdom$jid.sin 2>/dev/null - numdom=`echo $numdom | $AWK '{sum=$1-1}; {print sum}'` - done - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - if test $MPITYPE = "myrinet" - then - if test -f "$host_filt" - then - /bin/rm $host_filt - fi - fi -else - /bin/rm $DIRSCR/$jid.t02 2>/dev/null - /bin/rm $DIRSCR/$jid.t03 2>/dev/null - /bin/rm $DIRSCR/$jid.t11 2>/dev/null - /bin/rm $DIRSCR/$jid.t12 2>/dev/null - /bin/rm $DIRSCR/$jid.t13 2>/dev/null - /bin/rm $DIRSCR/$jid.t14 2>/dev/null - /bin/rm $DIRSCR/$jid.t15 2>/dev/null - /bin/rm $DIRSCR/$jid.t22 2>/dev/null - /bin/rm $DIRSCR/$jid.t23 2>/dev/null - /bin/rm $DIRSCR/$jid.t32 2>/dev/null - /bin/rm $DIRSCR/$jid.t33 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t81* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t82* 2>/dev/null - /bin/rm $DIRSCR/$jid.*.t83* 2>/dev/null - /bin/rm $DIRSCR/$jid.t84 2>/dev/null - /bin/rm $DIRJOB/$jid.pid 2>/dev/null - /bin/rm $DIRJOB/$jid.sle 2>/dev/null - /bin/rm $DIRJOB/$jid.sin 2>/dev/null -fi - - -fi -fi diff --git a/installation/mods_MarcMentat/2019/Mentat_bin/edit_window b/installation/mods_MarcMentat/2019/Mentat_bin/edit_window deleted file mode 100644 index b732a7694..000000000 --- a/installation/mods_MarcMentat/2019/Mentat_bin/edit_window +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -# This script opens a window running an editor. -# The command to invoke the editor is specified during DAMASK installation - -%EDITOR% $* \ No newline at end of file diff --git a/installation/mods_MarcMentat/2019/Mentat_bin/edit_window.original b/installation/mods_MarcMentat/2019/Mentat_bin/edit_window.original deleted file mode 100644 index 64c0a68d0..000000000 --- a/installation/mods_MarcMentat/2019/Mentat_bin/edit_window.original +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh -# This script opens a window running an editor. The default window is an -# xterm, and the default editor is vi. These may be customized. - -dir= -for d in /usr/bin /usr/bin/X11; do - if test -x "$d/xterm"; then - dir="$d" - break - fi -done - -if test -z "$dir"; then - echo "$0: Could not find xterm" - exit 1 -fi - -"$dir/xterm" -T "vi $*" -n "vi $*" -e vi $* diff --git a/installation/mods_MarcMentat/2019/Mentat_bin/kill1.original b/installation/mods_MarcMentat/2019/Mentat_bin/kill1.original deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2019/Mentat_bin/kill1.original +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2019/Mentat_bin/kill4 b/installation/mods_MarcMentat/2019/Mentat_bin/kill4 deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2019/Mentat_bin/kill4 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2019/Mentat_bin/kill5 b/installation/mods_MarcMentat/2019/Mentat_bin/kill5 deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2019/Mentat_bin/kill5 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2019/Mentat_bin/kill6 b/installation/mods_MarcMentat/2019/Mentat_bin/kill6 deleted file mode 100644 index 6d1ff84bf..000000000 --- a/installation/mods_MarcMentat/2019/Mentat_bin/kill6 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = "" ]; then - echo "usage: $0 job_name" - exit 1 -fi - -echo STOP > $1.cnt diff --git a/installation/mods_MarcMentat/2019/Mentat_bin/submit1.original b/installation/mods_MarcMentat/2019/Mentat_bin/submit1.original deleted file mode 100644 index 094dea194..000000000 --- a/installation/mods_MarcMentat/2019/Mentat_bin/submit1.original +++ /dev/null @@ -1,189 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=/tmp/msc/marc2019 -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -copy_datfile="-ci $4" -copy_postfile="-cr $5" -scr_dir=$6 -dcoup=$7 -assem_recov_nthread=$8 -nthread=$9 -shift 9 # cannot use $10, $11, ... -nsolver=$1 -mode=$2 -gpu=$3 - -if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then - slv="-iam sfm" -fi -if [ "$slv" == "marc" ]; then - slv="" -fi -if [ "$slv" == "datfit" ]; then - slv="-iam datfit" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_marc" $slv -j $job -v n -b y $nprocds $nprocd \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2019/Mentat_bin/submit4 b/installation/mods_MarcMentat/2019/Mentat_bin/submit4 deleted file mode 100644 index 55e3bcf03..000000000 --- a/installation/mods_MarcMentat/2019/Mentat_bin/submit4 +++ /dev/null @@ -1,191 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=%INSTALLDIR%/marc%VERSION% - -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -copy_datfile="-ci $4" -copy_postfile="-cr $5" -scr_dir=$6 -dcoup=$7 -assem_recov_nthread=$8 -nthread=$9 -shift 9 # cannot use $10, $11, ... -nsolver=$1 -mode=$2 -gpu=$3 - -if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then - slv="-iam sfm" -fi -if [ "$slv" = "marc" ]; then - slv="" -fi -if [ "$slv" = "datfit" ]; then - slv="-iam datfit" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile=${srcfile%.*}".marc" - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_damask_hmp" $slv -j $job -v n -b y $nprocds $nprocd \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2019/Mentat_bin/submit5 b/installation/mods_MarcMentat/2019/Mentat_bin/submit5 deleted file mode 100644 index 8699cf076..000000000 --- a/installation/mods_MarcMentat/2019/Mentat_bin/submit5 +++ /dev/null @@ -1,191 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=%INSTALLDIR%/marc%VERSION% - -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -copy_datfile="-ci $4" -copy_postfile="-cr $5" -scr_dir=$6 -dcoup=$7 -assem_recov_nthread=$8 -nthread=$9 -shift 9 # cannot use $10, $11, ... -nsolver=$1 -mode=$2 -gpu=$3 - -if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then - slv="-iam sfm" -fi -if [ "$slv" = "marc" ]; then - slv="" -fi -if [ "$slv" = "datfit" ]; then - slv="-iam datfit" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile=${srcfile%.*}".marc" - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_damask_mp" $slv -j $job -v n -b y $nprocds $nprocd \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2019/Mentat_bin/submit6 b/installation/mods_MarcMentat/2019/Mentat_bin/submit6 deleted file mode 100644 index a0179482f..000000000 --- a/installation/mods_MarcMentat/2019/Mentat_bin/submit6 +++ /dev/null @@ -1,191 +0,0 @@ -#!/bin/sh -# -# The exit status of this script is read by Mentat. -# Normal exit status is 0. -# - -DIR=%INSTALLDIR%/marc%VERSION% - -if test $MARCDIR1 -then - DIR=$MARCDIR1 -fi - -if test -z "$DIR"; then - REALCOM="`ls -l $0 |awk '{ print $NF; }'`" - DIRSCRIPT=`dirname $REALCOM` - case $DIRSCRIPT in - \/*) - ;; - *) - DIRSCRIPT=`pwd`/$DIRSCRIPT - ;; - esac - . $DIRSCRIPT/getarch - - DIR="$MENTAT_MARCDIR" -fi - -SRCEXT=.f -SRCEXTC=.F -RSTEXT=.t08 -PSTEXT=.t19 -PSTEXTB=.t16 -VWFCEXT=.vfs - -slv=$1 -version=$2 -ndom_fea_solver=$3 -ndom_preprocessor=$4 -hostfile=$5 -compat=$6 -job=$7 -srcfile=$8 -srcmeth=$9 -shift 9 # cannot use $10, $11, ... -restart=$1 -postfile=$2 -viewfactorsfile=$3 -copy_datfile="-ci $4" -copy_postfile="-cr $5" -scr_dir=$6 -dcoup=$7 -assem_recov_nthread=$8 -nthread=$9 -shift 9 # cannot use $10, $11, ... -nsolver=$1 -mode=$2 -gpu=$3 - -if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then - slv="-iam sfm" -fi -if [ "$slv" = "marc" ]; then - slv="" -fi -if [ "$slv" = "datfit" ]; then - slv="-iam datfit" -fi - -if [ "$ndom_fea_solver" != "" -a "$ndom_fea_solver" != "1" ]; then - nprocds="-nprocds $ndom_fea_solver" -else - nprocd="" - if [ "$ndom_preprocessor" != "" -a "$ndom_preprocessor" != "1" ]; then - nprocd="-nprocd $ndom_preprocessor" - else - nprocd="" - fi -fi - -if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then - srcfile=`echo $srcfile | sed "s/$SRCEXT$//" | sed "s/$SRCEXTC$//"` - case "$srcmeth" in - -) - srcfile="-u $srcfile" - ;; - compsave) - srcfile="-u $srcfile -save y" - ;; - runsaved) - srcfile=${srcfile%.*}".marc" - srcfile="-prog $srcfile" - ;; - esac -else - srcfile="" -fi - -if [ "$restart" != "" -a "$restart" != "-" ]; then - restart=`echo $restart | sed "s/$RSTEXT$//"` - restart="-r $restart" -else - restart="" -fi - -if [ "$postfile" != "" -a "$postfile" != "-" ]; then - postfile=`echo $postfile | sed "s/$PSTEXT$//"` - postfile=`echo $postfile | sed "s/$PSTEXTB$//"` - postfile="-pid $postfile" -else - postfile="" -fi - -if [ "$viewfactorsfile" != "" -a "$viewfactorsfile" != "-" ]; then - viewfactorsfile=`echo $viewfactorsfile | sed "s/$VWFCEXT$//"` - viewfactorsfile="-vf $viewfactorsfile" -else - viewfactorsfile="" -fi - -if [ "$hostfile" != "" -a "$hostfile" != "-" ]; then - hostfile="-ho $hostfile" -else - hostfile="" -fi - -if [ "$compat" != "" -a "$compat" != "-" ]; then - compat="-co $compat" -else - compat="" -fi - -if [ "$scr_dir" != "" -a "$scr_dir" != "-" ]; then - scr_dir="-sd $scr_dir" -else - scr_dir="" -fi - -if [ "$dcoup" != "" -a "$dcoup" != "0" ]; then - dcoup="-dcoup $dcoup" -else - dcoup="" -fi - -if [ "$assem_recov_nthread" != "" -a "$assem_recov_nthread" != "1" ]; then - assem_recov_nthread="-nthread_elem $assem_recov_nthread" -else - assem_recov_nthread="" -fi - -if [ "$nthread" != "" -a "$nthread" != "0" -a "$nthread" != "1" ]; then - nthread="-nthread $nthread" -else - nthread="" -fi - -if [ "$nsolver" != "" -a "$nsolver" != "0" ]; then - nsolver="-nsolver $nsolver" -else - nsolver="" -fi - -case "$mode" in - 4) mode="-mo i4" ;; - 8) mode="-mo i8" ;; - *) mode= ;; -esac - -if [ "$gpu" != "" -a "$gpu" != "-" ]; then - gpu="-gpu $gpu" -else - gpu="" -fi - -rm -f $job.cnt -rm -f $job.sts -rm -f $job.out -rm -f $job.log - -# To prevent a mismatch with the python version used by the solver -# do *not* prepend $MENTAT_INSTALL_DIR/python/bin to environment variable PATH -# unset environment variables PYTHONHOME and PYTHONPATH -unset PYTHONHOME -unset PYTHONPATH - -"${DIR}/tools/run_damask_lmp" $slv -j $job -v n -b y $nprocds $nprocd \ - $srcfile $restart $postfile $viewfactorsfile $hostfile \ - $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ - $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 -sleep 1 -exit 0 diff --git a/installation/mods_MarcMentat/2019/Mentat_menus/job_run.ms b/installation/mods_MarcMentat/2019/Mentat_menus/job_run.ms deleted file mode 100644 index 89eadf8df..000000000 --- a/installation/mods_MarcMentat/2019/Mentat_menus/job_run.ms +++ /dev/null @@ -1,2708 +0,0 @@ -#ifndef AUTOFORGE -popmenu job_title_pm file jobs.ms -popdown job_title_ok file jobs.ms - -group user_domains_gr file domain_decomposition.ms -group user_domains_generate_gr file domain_decomposition.ms -group user_domains_tail_gr file domain_decomposition.ms -group matrix_solver_gr file job_common.ms -popmenu ddm_options file job_common.ms - -browser edit_browser file file.ms -browser directory_browser file file.ms -screen domains file domain_decomposition.ms - - - - browser usersub_file_browser { - position 0 0 - size 82 72 - text "$usersub_file_browser_label" ($usersub_file_browser_label) - filter "*.f *.F *.f90 *.F90" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$usersub_file_browser_command" ($usersub_file_browser_command) - } - - - - browser host_file_browser { - position 0 0 - size 82 72 - text "$host_file_browser_label" ($host_file_browser_label) - filter "*" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$host_file_browser_command" ($host_file_browser_command) - } - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_popmenu { - - text "RUN JOB" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - button { - position 1 9 - size 24 4 - text "USER SUBROUTINE FILE" - browser usersub_file_browser - settext $usersub_file_browser_label "SELECT USER SUBROUTINE FILE" - set $usersub_file_browser_command "*job_usersub_file" - help job_usersub_file - } - - toggle { - position +26 = - size 22 4 - text "SELECTED USER SUBS" - toggle job_usersubs - help job_run_seluser - visible job_usersubs - popmenu job_usersub_pm - } - - display { - position 1 +4 - size 50 4 - display job_usersub_file - } - - button { - position 1 +4 - size 12 4 - text "EDIT" - command "*job_edit_usersub_file" - visible job_usersub_file - } - - button { - position +12 = - size 12 4 - text "CLEAR" - command "*job_clear_usersub_file" - visible job_usersub_file - } - - roller { - position +12 = - size 26 4 - nvalues 3 - texts "COMPILE / NO SAVE" - "COMPILE AND SAVE" - "RUN SAVED EXECUTABLE" - help job_run_compile - roller "job_option user_source" - visible job_usersub_file - commands "*job_option user_source:compile_nosave" - "*job_option user_source:compile_save" - "*job_option user_source:run_saved" - } - - button { - position 1 +6 - size 24 4 - text "SOLVER/PARALLELIZATION" - help job_run_parallel - popmenu job_run_parallelization_pm - set $popname2 "job_run_parallelization_pm" - } - frame { - position 1 +4 - size 48 16 - border_width 1 - border_color black - - group{ - layout hbox - frame { - position 0 0 - size 24 16 - group { - layout vbox - - display { - position 0 0 - size 24 4 - display job_solver_solution - } - - display { - position = +4 - size 24 4 - display job_solver_type - } - spacer { - stretch 1 - } - - } - } - - frame { - position +22 = - size 24 16 - border_width 1 - border_color black - - group { - #layout vbox - display { - position = +4 - size 24 4 - display job_ddm_domains - } - - display { - position = +4 - size 24 4 - display job_assem_recov_nthreads - } - - display { - position = +4 - size 24 4 - display job_solver_procs - visible solver_allows_multi_procs - } - - display { - position = = - size 24 4 - display job_solver_threads - visible "and(solver_allows_multi_threads,\ - not(and(job_solver_mfront_sparse,\ - *job_option parallel:on)))" - } - - display { - position = +4 - size 24 4 - display job_solver_gpu - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } - } - } - } - } - - button { - position 1 +18 - size 8 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - -# see also job_common.ms -# see also the ADVANCED JOB SUBMISSION popmenu in this file - - label { - position +10 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - button { - position +20 = - size 13 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position 1 +6 - size 16 6 - text "SUBMIT (1)" - command "*submit_job 1 *monitor_job" - } - - button { - position +16 = - size 16 6 - text "ADVANCED JOB SUBMISSION" - popmenu job_submit_adv_pm - } - - button { - position +16 = - size 18 6 - text "DAMASK" - popmenu damask - } - - button { - position 1 +6 - size 16 6 - text "UPDATE" - command "*update_job" - } - - button { - position +16 = - size 16 6 - text "MONITOR" - command "*monitor_job" - } - - button { - position +16 = - size 18 6 - text "KILL" - command "*kill_job *monitor_job" - } - - label { - position 1 +7 - size 32 4 - text "STATUS" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_status" - } - - label { - position -32 +4 - size 32 4 - text "CURRENT INCREMENT (CYCLE)" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_increment" - } - - label { - position -32 +4 - size 32 4 - text "SINGULARITY RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_singularity_ratio" - } - - label { - position -32 +4 - size 32 4 - text "CONVERGENCE RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_convergence_ratio" - } - - label { - position 1 +4 - size 32 4 - text "ANALYSIS TIME" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_analysis_time" - } - - label { - position -32 +4 - size 32 4 - text "WALL TIME" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_time" - } - - frame { - position 1 +4 - size 50 8 - - group { - - frame { - position 0 0 - size 50 8 - text "TOTAL" - border_width 1 - border_color black - group { - - label { - position +6 = - size 13 4 - text "CYCLES" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_cycles" - border_width 1 - border_color black - } - - label { - position -13 +4 - size 13 4 - text "SEPARATIONS" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_separations" - border_width 1 - border_color black - } - - label { - position +10 -4 - size 11 4 - text "CUT BACKS" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_cut_backs" - border_width 1 - border_color black - } - - label { - position -11 +4 - size 11 4 - text "REMESHES" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_remeshes" - border_width 1 - border_color black - } - } - } - } - } - - label { - position 1 +8 - size 19 4 - text "EXIT NUMBER" - border_width 1 - border_color black - } - - integer { - position +19 = - size 10 4 - display "job_exit" - } - - button { - position +10 = - size 21 4 - text "EXIT MESSAGE" - popmenu job_exit_msg_pm - help exit_message - } - - label { - position 1 +6 - size 7 4 - text "EDIT" - border_width 1 - border_color black - } - - button { - position +7 = - size 12 4 - text "OUTPUT FILE" - command "*job_edit_output" - } - - button { - position +12 = - size 9 4 - text "LOG FILE" - command "*job_edit_log_file" - } - - button { - position +9 = - size 12 4 - text "STATUS FILE" - command "*job_edit_status_file" - } - - button { - position +12 = - size 10 4 - text "ANY FILE" - settext $edit_browser_label "EDIT FILE" - set $edit_browser_command "*edit_file" - browser edit_browser - help edit_file - } - - popdown { - position 1 +6 - size 32 4 - text "OPEN POST FILE (MODEL PLOT RESULTS MENU)" - command "@popdown(job_properties_pm) @main(results) @popup(modelplot_pm) *post_open_default" - } - - button { - position 1 +6 - size 12 8 - text "RESET" - command "*job_submit_reset" - } - - popdown { - position +38 = - size 12 8 - text "OK" - } - } - - window job_run_wi { - parent mentat - origin 35 1 - size 52 115 - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_usersub_pm { - - text "CURRENTLY SELECTED USER SUBROUTINES" - - group { - - - display { - position 1 +5 - size 64 86 - display "job_usersubs" - } - - popdown { - position 27 +88 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 66 102 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_submit_adv_pm { - - text "ADVANCED JOB SUBMISSION" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - label { - position 1 9 - size 19 4 - text "INITIAL ALLOCATION" - border_width 1 - border_color black - } - label { - position +19 = - size 15 4 - text "GENERAL MEMORY" - help job_param_general_init_allocation - } - text { - position +15 = - size 10 4 - display "job_param_value_general_init_allocation" - command "*job_param general_init_allocation" - help job_param_general_init_allocation - } - - label { - position +10 = - size 4 4 - text "MB" - border_width 1 - border_color black - } - - toggle { - position 1 +5 - size 32 4 - text "OUT-OF-CORE ELEMENT STORAGE" - help job_param_elsto - toggle "*job_option elsto:on" - true_command "*job_option elsto:on" - false_command "*job_option elsto:off" - } - - toggle { - position 1 +4 - size 32 4 - text "OUT-OF-CORE INCREMENTAL BACKUP" - help job_param_inc_backup_storage - toggle "*job_option inc_backup_storage:out_of_core" - true_command "*job_option inc_backup_storage:out_of_core" - false_command "*job_option inc_backup_storage:in_core" - } - - toggle { - position +34 = - size 14 4 - text "CHECK SIZES" - help job_run_check - toggle "*job_option check:on" - true_command "*job_option check:on" - false_command "*job_option check:off" - } - - frame { - position 1 +6 - size 48 12 - text "MARC INPUT FILE" - border_width 1 - border_color black - - group { - - label { - position 0 4 - size 9 4 - text "VERSION" - border_width 1 - border_color black - } - - roller { - position +9 = - size 14 4 - nvalues 27 - nvisible 27 - texts "DEFAULT" -#if 0 - "2019" -#endif - "2018.1" - "2018" - "2017.1" - "2017" - "2016" - "2015" - "2014.2" - "2014.1" - "2014" - "2013.1" - "2013" - "2012" - "2011" - "2010.2" - "2010" - "2008" - "2007" - "2005R3" - "2005" - "2003" - "2001" - "2000" -#if 0 - "8" -#endif - "K7" - "K6.2" - "K5" - "K4" - help job_param_version - rollers "job_input_version_default" -#if 0 - "job_input_version_2019" -#endif - "job_input_version_2018.1" - "job_input_version_2018" - "job_input_version_2017.1" - "job_input_version_2017" - "job_input_version_2016" - "job_input_version_2015" - "job_input_version_2014.2" - "job_input_version_2014.1" - "job_input_version_2014" - "job_input_version_2013.1" - "job_input_version_2013" - "job_input_version_2012" - "job_input_version_2011" - "job_input_version_2010.2" - "job_input_version_2010" - "job_input_version_2008" - "job_input_version_2007" - "job_input_version_2005r3" - "job_input_version_2005" - "job_input_version_2003" - "job_input_version_2001" - "job_input_version_2000" -#if 0 - "job_input_version_8" -#endif - "job_input_version_k7" - "job_input_version_k6" - "job_input_version_k5" - "job_input_version_k4" - commands "*job_option version:default" -#if 0 - "*job_option version:2019" -#endif - "*job_option version:2018.1" - "*job_option version:2018" - "*job_option version:2017.1" - "*job_option version:2017" - "*job_option version:2016" - "*job_option version:2015" - "*job_option version:2014.2" - "*job_option version:2014.1" - "*job_option version:2014" - "*job_option version:2013.1" - "*job_option version:2013" - "*job_option version:2012" - "*job_option version:2011" - "*job_option version:2010.2" - "*job_option version:2010" - "*job_option version:2008" - "*job_option version:2007" - "*job_option version:2005r3" - "*job_option version:2005" - "*job_option version:2003" - "*job_option version:2001" - "*job_option version:2000" -#if 0 - "*job_option version:8" -#endif - "*job_option version:k7" - "*job_option version:k6" - "*job_option version:k5" - "*job_option version:k4" - visibles "job_allows_input_version_default" -#if 0 - "job_allows_input_version_2019" -#endif - "job_allows_input_version_2018.1" - "job_allows_input_version_2018" - "job_allows_input_version_2017.1" - "job_allows_input_version_2017" - "job_allows_input_version_2016" - "job_allows_input_version_2015" - "job_allows_input_version_2014.2" - "job_allows_input_version_2014.1" - "job_allows_input_version_2014" - "job_allows_input_version_2013.1" - "job_allows_input_version_2013" - "job_allows_input_version_2012" - "job_allows_input_version_2011" - "job_allows_input_version_2010.2" - "job_allows_input_version_2010" - "job_allows_input_version_2008" - "job_allows_input_version_2007" - "job_allows_input_version_2005r3" - "job_allows_input_version_2005" - "job_allows_input_version_2003" - "job_allows_input_version_2001" - "job_allows_input_version_2000" -#if 0 - "job_allows_input_version_8" -#endif - "job_allows_input_version_k7" - "job_allows_input_version_k6" - "job_allows_input_version_k5" - "job_allows_input_version_k4" - } - -# see also job_common.ms -# see also the RUN JOB popmenu in this file - - label { - position +14 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - toggle { - position 0 +4 - size 24 4 - text "EXTENDED PRECISION" - help job_run_precision - toggle "*job_option inp_file_prec:extended" - true_command "*job_option inp_file_prec:extended" - false_command "*job_option inp_file_prec:normal" - } - toggle { - position +24 = - size 24 4 - text "INCLUDE UNUSED TABLES" - toggle "*job_option input_file_tables:all" - true_command "*job_option input_file_tables:all" - false_command "*job_option input_file_tables:used" - } - } - } - - button { - position 1 +14 - size 24 4 - text "SCRATCH DIRECTORY" - settext $directory_browser_label "JOB SCRATCH DIRECTORY" - set $directory_browser_command "*job_scratch_directory" - browser directory_browser - help job_scratch_directory - } - - button { - position +24 = - size 24 4 - text "CLEAR" - command "*job_clear_scratch_directory" - visible job_scratch_directory - } - - text { - position 1 +4 - size 48 4 - display job_scratch_dir - command "*job_scratch_directory" - } - -#ifdef DCOM - toggle { - position 1 +6 - size 8 4 - text "\{DCOM}" - toggle "*job_option dcom:on" - help job_run_dcom - true_command "*job_option dcom:on" - false_command "*job_option dcom:off" - visible win32_available - } - - button { - position +8 = - size 12 4 - text "HOSTNAME" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } - - text job_dcom_hostname { - position +12 = - size 28 4 - display "job_dcom_hostname" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } -#endif - - button { - position 1 +6 - size 24 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - - button { - position +24 = - size 24 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position +4 +6 - size 20 4 - text "WRITE INPUT FILE" - command "*job_write_input" - } - - button { - position = +4 - size 20 4 - text "EDIT INPUT FILE" - command "*job_edit_input" - } - - popdown { - position 1 +5 - size 20 6 - text "SUBMIT 1" - command "*submit_job 1 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 1" - command "*execute_job 1 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 2" - command "*submit_job 2 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 2" - command "*execute_job 2 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 3" - command "*submit_job 3 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 3" - command "*execute_job 3 *monitor_job" - } - - popdown { - position 19 +8 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 -#ifdef DCOM - size 50 100 -#else - size 50 94 -#endif - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - -#-------------------------------------------------------------------------------------------------- -popmenu damask { - -#ifdef QT_MENTAT - text "DAMASK.MPIE.DE" -#endif - - group { -#ifndef QT_MENTAT - label { - position 0 0 - size 50 4 - text "DAMASK.MPIE.DE" - } -#endif - - label { - position 1 6 - size 13 6 - text "Optimzation" - border_width 1 - border_color black - } - - label { - position +13 = - size 20 6 - text "write Input" - border_width 1 - border_color black - } - - label { - position +18 = - size 30 6 - text "do not write Inp." - border_width 1 - border_color black - } - - label { - position -32 +6 - size 12 6 - text "O2 / OpenMP" - border_width 1 - border_color black - } - - popdown { - position +12 = - size 20 6 - text "Submit" - command "*submit_job 4 *monitor_job" - } - - popdown { - position +20 = - size 20 6 - text "Execute" - command "*execute_job 4 *monitor_job" - } - - label { - position -32 +6 - size 12 6 - text "O1 / OpenMP" - border_width 1 - border_color black - } - - popdown { - position +12 = - size 20 6 - text "Submit" - command "*submit_job 5 *monitor_job" - } - - popdown { - position +20 = - size 20 6 - text "Execute" - command "*execute_job 5 *monitor_job" - } - - label { - position -32 +6 - size 12 6 - text "O0 / OpenMP" - border_width 1 - border_color black - } - - popdown { - position +12 = - size 20 6 - text "Submit" - command "*submit_job 6 *monitor_job" - } - - popdown { - position +20 = - size 20 6 - text "Execute" - command "*execute_job 6 *monitor_job" - } - - popdown { - position 19 +8 - size 12 8 - text "CANCEL" - } -} - - window { - parent mentat - origin 38 8 -#ifdef DCOM - size 50 100 -#else - size 50 94 -#endif - background_color body - border_width 1 - border_color border - buffering single - } - mode permanent -} - -#-------------------------------------------------------------------------------------------------- -popmenu job_exit_msg_pm { - - text "EXIT MESSAGE" - - group { - - - - text { - position 1 5 - size 84 74 - multiline - readonly - display "job_exit_msg" - } - - popdown { - position 37 +76 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 86 90 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_parallelization_pm { - - text "SOLVER/PARALLELIZATION" - - group { - layout vbox - frame { - position 0 0 - size 42 8 - group { - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 36 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 36 4 - display job_class_label - } - } - } - frame { - position 0 8 - size 42 20 - group job_ddm_gr - text "DOMAIN DECOMPOSITION" - border_width 1 - border_color black - } - - frame { - position 0 +20 - size 42 13 - group job_assem_recov_gr - text "ASSEMBLY AND RECOVERY" - border_width 1 - border_color black - } - - frame { - position 0 +14 - size 42 31 - group job_parallel_matrix_solver_gr - text "MATRIX SOLVER" - border_width 1 - border_color black - } - - frame { - position 0 +32 - size 42 28 - group job_parallel_env_gr - text "PARALLELIZATION ENVIRONMENT" - border_width 1 - border_color black - visible "or(*job_option parallel:on, \ - solver_multi_procs)" - } - frame { - position 15 +30 - size 42 8 - group { - layout hbox - - spacer { - stretch 1 - } - popdown { - position 15 0 - size 12 8 - text "OK" - } - spacer { - stretch 1 - } - } - } - - spacer { - spacing 2 - stretch 1 - } - } - - window { - parent mentat - origin 38 1 - size 60 119 - background_color body - border_width 1 - border_color border - buffering single - } - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_gr { - - toggle { - position 1 4 - size 42 4 - text "USE \{DDM}" - toggle "*job_option parallel:on" - help job_run_ddm_use - true_command "*job_option parallel:on" - false_command "*job_option parallel:off" - active "and(not(job_solver_it_ext),\ - not(job_solver_mixed_direct_iterative))" - } - - frame { - position = +5 - size 42 4 - group job_ddm_use_gr - visible "*job_option parallel:on" - } -} - -group job_ddm_use_gr { - layout vbox - frame{ - position 0 0 - size 30 4 - group { - layout hbox - label { - position 0 0 - size 12 4 - text "DECOMPOSITION IN" - help job_run_ddm_generator - } - oneonly{ - position +12 = - size 8 4 - text "MARC" - oneonly "*job_option ddm_generator:fea_solver" - command "*job_option ddm_generator:fea_solver" - help job_run_ddm_generator - } - oneonly{ - position +12 = - size 8 4 - text "MENTAT" - oneonly "*job_option ddm_generator:preprocessor" - command "*job_option ddm_generator:preprocessor" - help job_run_ddm_generator - } - } - } - - frame { - position 0 +5 - size 44 8 - group job_ddm_fea_solver_gr - visible "*job_option ddm_generator:fea_solver" - } - - frame { - position = = - size 44 8 - group job_ddm_preprocessor_gr - visible "*job_option ddm_generator:preprocessor" - } - - frame{ - position 0 +5 - size 40 4 - group{ - layout hbox - text { - position 0 0 - size 22 4 - text "Single Input File" - readonly - visible "*job_option ddm_generator:fea_solver" - } - - roller { - position = = - size 22 4 - nvalues 2 - texts "MULTIPLE INPUT FILES" - "SINGLE INPUT FILE" - roller "job_option ddm_single_input" - commands "*job_option ddm_single_input:off" - "*job_option ddm_single_input:on" - visible "*job_option ddm_generator:preprocessor" - help job_run_ddm_single_input - } - - roller { - position +23 = - size 21 4 - nvalues 2 - texts "MULTIPLE POST FILES" - "SINGLE POST FILE" - roller "job_option ddm_single_post" - commands "*job_option ddm_single_post:off" - "*job_option ddm_single_post:on" - help job_run_ddm_single_post - } - } - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_fea_solver_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - help job_param - } - - text { - position +10 = - size 4 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 0 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - button { - position +18 = - size 12 4 - text "ADV. SETTINGS" - popmenu job_ddm_fea_solver_pm - } -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_ddm_fea_solver_pm { - - text "JOB PARALLELIZATION" - - group { - units 32 120 - - - label { - position 0 5 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - frame { - - position 0 +9 - size 32 76 - text "ADVANCED DECOMPOSITION IN MARC" - border_width 1 - border_color black - - group { - - label { - position 1 4 - size 16 4 - text "# DOMAINS" - help job_param - } - - text { - position +16 = - size 14 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 1 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 23 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - frame { - position 1 +5 - size 30 20 - group job_ddm_direction_gr - visible "or(*job_option ddm_method:vector, \ - *job_option ddm_method:radial, \ - *job_option ddm_method:angular)" - } - - toggle { - position 1 +21 - size 30 4 - text "DOMAIN ISLAND REMOVAL" - toggle "*job_option ddm_island_removal:on" - true_command "*job_option ddm_island_removal:on" - false_command "*job_option ddm_island_removal:off" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "GRAPH" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "COARSE" - "FINE" - help ddm_decomp_coarse_graph - rollers "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - commands "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "QUADRATIC ELEMENTS" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "GENUINE" - "LINEARIZED" - help job_run_ddm_decomp_linearized - rollers "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - commands "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - } - - label { - position 1 +5 - size 15 4 - text "ELEMENT WEIGHT FACTOR" - help job_param - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_elem_weight_factor" - command "*job_param ddm_elem_weight_factor" - help job_run_ddm_decomp_element_weight_factor - } - - toggle { - position 1 +5 - size 30 4 - text "DETECT CONTACT" - toggle "*job_option ddm_detect_contact:on" - true_command "*job_option ddm_detect_contact:on" - false_command "*job_option ddm_detect_contact:off" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - help job_run_ddm_decomp_detect_contact - } - - label { - position = +5 - size 15 4 - text "CONTACT TOLERANCE" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - command "*set_ddm_contact_tolerance" - display "job_param_value_ddm_contact_tolerance" - command "*job_param ddm_contact_tolerance" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_tolerance - } - - label { - position -15 +4 - size 15 4 - text "CONTACT CONSTR FACTOR" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_contact_constr_factor" - command "*job_param ddm_contact_constr_factor" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_constraint_factor - } - } - } - - popdown { - position 0 +77 - size 32 8 - text "OK" - } - } - mode permanent -} # job_ddm_fea_solver_pm - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_direction_gr { - - button { - position 0 0 - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "*job_option ddm_method:vector" - } - - button { - position = = - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "not(*job_option ddm_method:vector)" - } - - button { - position +15 = - size 15 4 - text "FROM / TO" - command "*job_vector_from_to ddm_sort_direction_x" - } - - text { - position -15 +4 - size 10 4 - command "*job_param ddm_sort_direction_x" - display "job_param_value_ddm_sort_direction_x" - help ddm_job_decomp_user_direction_x - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_y" - display "job_param_value_ddm_sort_direction_y" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_z" - display "job_param_value_ddm_sort_direction_z" - } - - frame { - position 0 +4 - size 30 8 - group job_ddm_sort_point_gr - visible "not(*job_option ddm_method:vector)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_sort_point_gr { - - label { - position 0 0 - size 14 4 - border_width 1 - border_color black - text "POINT ON AXIS" - } - - roller { - position +14 = - size 10 4 - nvalues 2 - texts "DEFAULT" - "USER" - roller "job_option ddm_sort_point" - commands "*job_option ddm_sort_point:default" - "*job_option ddm_sort_point:user" - } - - button { - position +10 = - size 6 4 - text "SET" - command "*job_position ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position 0 +4 - size 10 4 - command "*job_param ddm_sort_point_x" - display "job_param_value_ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_y" - display "job_param_value_ddm_sort_point_y" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_z" - display "job_param_value_ddm_sort_point_z" - visible "*job_option ddm_sort_point:user" - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_preprocessor_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - border_width 1 - border_color black - } - - integer { - position +10 = - size 4 4 - display valid_domains - } - - button { - position 0 +4 - size 30 4 - text "USER DOMAINS" - popmenu domains_pm - help job_run_ddm_user_domains - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_assem_recov_gr { - - toggle { - position 1 +4 - size 30 4 - text "MULTIPLE THREADS" - true_command "*job_option assem_recov_multi_threading:on" - false_command "*job_option assem_recov_multi_threading:off" - toggle "*job_option assem_recov_multi_threading:on" - } - - label { - position = +4 - size 12 4 - text "# THREADS" - visible "*job_option assem_recov_multi_threading:on" - } - - text { - position +12 = - size 4 4 - display "job_param_value_assem_recov_nthreads" - command "*job_param assem_recov_nthreads" - visible "*job_option assem_recov_multi_threading:on" - } - - label { - position +4 = - size 10 4 - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - } - - display { - position +12 = - size 4 4 - display "job_assem_recov_nthreads_dom" - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - } - spacer{ - stretch 2 - } - -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_matrix_solver_gr { - layout vbox - frame { - position 1 0 - size 36 31 - group { - layout hbox - label { - position 3 4 - size 12 4 - text "SOLUTION" - border_width 1 - border_color black - } - oneonly { - position +12 = - size 12 4 - text "SYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_off" - command "*job_option solver_nonsym:off" - } - oneonly { - position +12 = - size 12 4 - text "NONSYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_on" - command "*job_option solver_nonsym:on" - } - spacer { - stretch 1 - } - } - } - - frame { - position 1 +5 - size 42 23 - group matrix_solver_gr - help job_param_solver - } - - frame { - position +1 = - size 42 4 - group job_run_solver_ddm_opts_gr - visible "*job_option parallel:on" - } - - frame { - position 1 +23 - size 42 8 - group job_solver_multi_procs_gr - visible solver_allows_multi_procs - } - - frame { - position = = - size 42 8 - group job_solver_multi_threads_gr - visible solver_allows_multi_threads - } - - frame { - position 1 +9 - size 42 8 - group job_solver_gpu_gr - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } - -} - - -#-------------------------------------------------------------------------------------------------- -group job_run_solver_ddm_opts_gr { - - button { - position 0 0 - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options -# see also job_common.ms! - visible "not(or(job_solver_it_sparse, \ - job_solver_it_ext, \ - job_solver_mixed_direct_iterative, \ - job_solver_pardiso,\ - job_solver_mumps))" - } - button { - position = = - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options_mumps - visible "job_solver_mumps" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_gr { - frame { - position 0 0 - size 42 8 - group job_solver_multi_procs_parallel_off_gr - visible "*job_option parallel:off" - } - - frame { - position = = - size 42 8 - group job_solver_multi_procs_parallel_on_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - true_command "*job_option nsolver_procs_serial:on" - false_command "*job_option nsolver_procs_serial:off" - toggle "*job_option nsolver_procs_serial:on" - help job_run_multithreading - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - visible "*job_option nsolver_procs_serial:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - visible "*job_option nsolver_procs_serial:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - border_width 1 - border_color black - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - help job_run_multithreading - rollers "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_nsolver_procs_ddm_automatic_gr - visible "*job_option nsolver_procs_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_nsolver_procs_ddm_user_gr - visible "*job_option nsolver_procs_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - } -} - -group job_solver_multi_threads_gr { - frame { - position 0 0 - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_off_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:off)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_on_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:on)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_pardiso_parallel_off_gr - visible "and(job_solver_pardiso,*job_option parallel:off)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_pardiso_parallel_on_gr - visible "and(job_solver_pardiso,*job_option parallel:on)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_it_ext_off_gr - visible "and(job_solver_it_ext,*job_option parallel:off)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option mfront_sparse_multi_threading:on" - true_command "*job_option mfront_sparse_multi_threading:on" - false_command "*job_option mfront_sparse_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option mfront_sparse_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option mfront_sparse_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +30 0 - size 12 4 - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - } - - display { - position +12 0 - size 4 4 - display "job_mfront_sparse_nthreads_dom" - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - } - - label { - position 0 +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_automatic_gr - visible "*job_option mfront_sparse_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_user_gr - visible "*job_option mfront_sparse_multi_threading_ddm:user" - } -} -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - - - -#-------------------------------------------------------------------------------------------------- -group job_solver_gpu_gr { - - toggle { - position 0 0 - size 30 4 - text "USE \{GPU(s)}" - toggle "*job_option solver_use_gpu:on" - true_command "*job_option solver_use_gpu:on" - false_command "*job_option solver_use_gpu:off" - help job_solver_gpu - } - frame{ - position 0 +4 - size 28 4 - group{ - layout hbox - - label { - position 0 0 - size 16 4 - text "\{GPU} SELECTION" - border_width 1 - border_color black - visible "*job_option solver_use_gpu:on" - } - - roller { - position +16 = - size 12 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - rollers "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - visible "*job_option solver_use_gpu:on" - help job_solver_gpu - } - - text { - position +12 = - size 12 4 - display job_solver_gpus - command "*clear_job_solver_gpus *job_solver_gpus" - visible "and(*job_option solver_use_gpu:on,*job_option solver_gpus:user)" - } - spacer { - stretch 1 - } - } - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option pardiso_multi_threading:on" - true_command "*job_option pardiso_multi_threading:on" - false_command "*job_option pardiso_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option pardiso_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option pardiso_multi_threading:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position = +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_pardiso_multi_threads_ddm_automatic_gr - visible "*job_option pardiso_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_pardiso_multi_threads_ddm_user_gr - visible "*job_option pardiso_multi_threading_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_it_ext_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option it_ext_multi_threading:on" - true_command "*job_option it_ext_multi_threading:on" - false_command "*job_option it_ext_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option it_ext_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option it_ext_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_gr { - - frame{ - position 0 +4 - size 40 4 - group{ - layout hbox - label{ - position 0 0 - size 8 4 - text "SETUP" - help job_run_ddm_setup - } - oneonly { - position +12 = - size 12 4 - text "SINGLE MACHINE" - oneonly "*job_option parallel_setup:single" - command "*job_option parallel_setup:single" - help job_run_ddm_setup - } - oneonly { - position +8 = - size 12 4 - text "NETWORK" - oneonly "*job_option parallel_setup:network" - command "*job_option parallel_setup:network" - help job_run_ddm_setup - } - - spacer { - stretch 1 - } - } - } - - - frame { - position +1 +5 - size 40 16 - group job_parallel_env_network_gr - visible "*job_option parallel_setup:network" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_gr { - - button { - position 0 0 - size 28 4 - text "HOST FILE" - browser host_file_browser - settext $host_file_browser_label "SELECT HOST FILE" - set $host_file_browser_command "*job_host_file" - help job_host_file - } - - button { - position +28 = - size 8 4 - text "EDIT" - command "*job_edit_host_file" - help job_edit_host_file - visible job_host_file - } - - button { - position +8 = - size 8 4 - text "CLEAR" - command "*job_clear_host_file" - help job_clear_host_file - visible job_host_file - } - - display { - position 0 +4 - size 44 4 - display job_host_file - } - - frame { - position 0 +5 - size 44 9 - group job_parallel_env_network_ddm_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_ddm_gr { - - toggle { - position 0 0 - size 22 4 - text "COPY INPUT FILE" - toggle "*job_option copy_input_file:on" - true_command "*job_option copy_input_file:on" - false_command "*job_option copy_input_file:off" - help job_host_copy_inputfile - } - - toggle { - position +23 = - size 21 4 - text "COPY POST FILE" - toggle "*job_option copy_post_file:on" - true_command "*job_option copy_post_file:on" - false_command "*job_option copy_post_file:off" - help job_host_copy_inputfile - } - - label { - position 0 +5 - size 10 4 - text "HOSTS" - border_width 1 - border_color black - visible job_usersub_file - } - - roller { - position +10 = - size 18 4 - nvalues 2 - texts "COMPATIBLE" - "INCOMPATIBLE" - roller "job_option network_hosts" - commands "*job_option network_hosts:compatible" - "*job_option network_hosts:incompatible" - help job_host_comp - visible job_usersub_file - } -} - - -#endif diff --git a/installation/mods_MarcMentat/2019/Mentat_menus/job_run.ms.original b/installation/mods_MarcMentat/2019/Mentat_menus/job_run.ms.original deleted file mode 100644 index dac74a50c..000000000 --- a/installation/mods_MarcMentat/2019/Mentat_menus/job_run.ms.original +++ /dev/null @@ -1,2573 +0,0 @@ -#ifndef AUTOFORGE -popmenu job_title_pm file jobs.ms -popdown job_title_ok file jobs.ms - -group user_domains_gr file domain_decomposition.ms -group user_domains_generate_gr file domain_decomposition.ms -group user_domains_tail_gr file domain_decomposition.ms -group matrix_solver_gr file job_common.ms -popmenu ddm_options file job_common.ms - -browser edit_browser file file.ms -browser directory_browser file file.ms -screen domains file domain_decomposition.ms - - - - browser usersub_file_browser { - position 0 0 - size 82 72 - text "$usersub_file_browser_label" ($usersub_file_browser_label) - filter "*.f *.F *.f90 *.F90" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$usersub_file_browser_command" ($usersub_file_browser_command) - } - - - - browser host_file_browser { - position 0 0 - size 82 72 - text "$host_file_browser_label" ($host_file_browser_label) - filter "*" - nvisible 10 - select_files true - cancel_action popdown - ok_action popdown - command "$host_file_browser_command" ($host_file_browser_command) - } - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_popmenu { - - text "RUN JOB" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - button { - position 1 9 - size 24 4 - text "USER SUBROUTINE FILE" - browser usersub_file_browser - settext $usersub_file_browser_label "SELECT USER SUBROUTINE FILE" - set $usersub_file_browser_command "*job_usersub_file" - help job_usersub_file - } - - toggle { - position +26 = - size 22 4 - text "SELECTED USER SUBS" - toggle job_usersubs - help job_run_seluser - visible job_usersubs - popmenu job_usersub_pm - } - - display { - position 1 +4 - size 50 4 - display job_usersub_file - } - - button { - position 1 +4 - size 12 4 - text "EDIT" - command "*job_edit_usersub_file" - visible job_usersub_file - } - - button { - position +12 = - size 12 4 - text "CLEAR" - command "*job_clear_usersub_file" - visible job_usersub_file - } - - roller { - position +12 = - size 26 4 - nvalues 3 - texts "COMPILE / NO SAVE" - "COMPILE AND SAVE" - "RUN SAVED EXECUTABLE" - help job_run_compile - roller "job_option user_source" - visible job_usersub_file - commands "*job_option user_source:compile_nosave" - "*job_option user_source:compile_save" - "*job_option user_source:run_saved" - } - - button { - position 1 +6 - size 24 4 - text "SOLVER/PARALLELIZATION" - help job_run_parallel - popmenu job_run_parallelization_pm - set $popname2 "job_run_parallelization_pm" - } - frame { - position 1 +4 - size 48 16 - border_width 1 - border_color black - - group{ - layout hbox - frame { - position 0 0 - size 24 16 - group { - layout vbox - - display { - position 0 0 - size 24 4 - display job_solver_solution - } - - display { - position = +4 - size 24 4 - display job_solver_type - } - spacer { - stretch 1 - } - - } - } - - frame { - position +22 = - size 24 16 - border_width 1 - border_color black - - group { - #layout vbox - display { - position = +4 - size 24 4 - display job_ddm_domains - } - - display { - position = +4 - size 24 4 - display job_assem_recov_nthreads - } - - display { - position = +4 - size 24 4 - display job_solver_procs - visible solver_allows_multi_procs - } - - display { - position = = - size 24 4 - display job_solver_threads - visible "and(solver_allows_multi_threads,\ - not(and(job_solver_mfront_sparse,\ - *job_option parallel:on)))" - } - - display { - position = +4 - size 24 4 - display job_solver_gpu - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } - } - } - } - } - - button { - position 1 +18 - size 8 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - -# see also job_common.ms -# see also the ADVANCED JOB SUBMISSION popmenu in this file - - label { - position +10 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - button { - position +20 = - size 13 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position 1 +6 - size 16 6 - text "SUBMIT (1)" - command "*submit_job 1 *monitor_job" - } - - button { - position +16 = - size 34 6 - text "ADVANCED JOB SUBMISSION" - popmenu job_submit_adv_pm - } - - button { - position 1 +6 - size 16 6 - text "UPDATE" - command "*update_job" - } - - button { - position +16 = - size 16 6 - text "MONITOR" - command "*monitor_job" - } - - button { - position +16 = - size 18 6 - text "KILL" - command "*kill_job *monitor_job" - } - - label { - position 1 +7 - size 32 4 - text "STATUS" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_status" - } - - label { - position -32 +4 - size 32 4 - text "CURRENT INCREMENT (CYCLE)" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_increment" - } - - label { - position -32 +4 - size 32 4 - text "SINGULARITY RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_singularity_ratio" - } - - label { - position -32 +4 - size 32 4 - text "CONVERGENCE RATIO" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_convergence_ratio" - } - - label { - position 1 +4 - size 32 4 - text "ANALYSIS TIME" - border_width 1 - border_color black - } - - float { - position +32 = - size 18 4 - display "job_analysis_time" - } - - label { - position -32 +4 - size 32 4 - text "WALL TIME" - border_width 1 - border_color black - } - - display { - position +32 = - size 18 4 - display "job_time" - } - - frame { - position 1 +4 - size 50 8 - - group { - - frame { - position 0 0 - size 50 8 - text "TOTAL" - border_width 1 - border_color black - group { - - label { - position +6 = - size 13 4 - text "CYCLES" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_cycles" - border_width 1 - border_color black - } - - label { - position -13 +4 - size 13 4 - text "SEPARATIONS" - border_width 1 - border_color black - } - - integer { - position +13 = - size 10 4 - display "acc_job_separations" - border_width 1 - border_color black - } - - label { - position +10 -4 - size 11 4 - text "CUT BACKS" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_cut_backs" - border_width 1 - border_color black - } - - label { - position -11 +4 - size 11 4 - text "REMESHES" - border_width 1 - border_color black - } - - integer { - position +11 = - size 10 4 - display "acc_job_remeshes" - border_width 1 - border_color black - } - } - } - } - } - - label { - position 1 +8 - size 19 4 - text "EXIT NUMBER" - border_width 1 - border_color black - } - - integer { - position +19 = - size 10 4 - display "job_exit" - } - - button { - position +10 = - size 21 4 - text "EXIT MESSAGE" - popmenu job_exit_msg_pm - help exit_message - } - - label { - position 1 +6 - size 7 4 - text "EDIT" - border_width 1 - border_color black - } - - button { - position +7 = - size 12 4 - text "OUTPUT FILE" - command "*job_edit_output" - } - - button { - position +12 = - size 9 4 - text "LOG FILE" - command "*job_edit_log_file" - } - - button { - position +9 = - size 12 4 - text "STATUS FILE" - command "*job_edit_status_file" - } - - button { - position +12 = - size 10 4 - text "ANY FILE" - settext $edit_browser_label "EDIT FILE" - set $edit_browser_command "*edit_file" - browser edit_browser - help edit_file - } - - popdown { - position 1 +6 - size 32 4 - text "OPEN POST FILE (MODEL PLOT RESULTS MENU)" - command "@popdown(job_properties_pm) @main(results) @popup(modelplot_pm) *post_open_default" - } - - button { - position 1 +6 - size 12 8 - text "RESET" - command "*job_submit_reset" - } - - popdown { - position +38 = - size 12 8 - text "OK" - } - } - - window job_run_wi { - parent mentat - origin 35 1 - size 52 115 - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_usersub_pm { - - text "CURRENTLY SELECTED USER SUBROUTINES" - - group { - - - display { - position 1 +5 - size 64 86 - display "job_usersubs" - } - - popdown { - position 27 +88 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 66 102 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_submit_adv_pm { - - text "ADVANCED JOB SUBMISSION" - - group { - - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - label { - position 1 9 - size 19 4 - text "INITIAL ALLOCATION" - border_width 1 - border_color black - } - label { - position +19 = - size 15 4 - text "GENERAL MEMORY" - help job_param_general_init_allocation - } - text { - position +15 = - size 10 4 - display "job_param_value_general_init_allocation" - command "*job_param general_init_allocation" - help job_param_general_init_allocation - } - - label { - position +10 = - size 4 4 - text "MB" - border_width 1 - border_color black - } - - toggle { - position 1 +5 - size 32 4 - text "OUT-OF-CORE ELEMENT STORAGE" - help job_param_elsto - toggle "*job_option elsto:on" - true_command "*job_option elsto:on" - false_command "*job_option elsto:off" - } - - toggle { - position 1 +4 - size 32 4 - text "OUT-OF-CORE INCREMENTAL BACKUP" - help job_param_inc_backup_storage - toggle "*job_option inc_backup_storage:out_of_core" - true_command "*job_option inc_backup_storage:out_of_core" - false_command "*job_option inc_backup_storage:in_core" - } - - toggle { - position +34 = - size 14 4 - text "CHECK SIZES" - help job_run_check - toggle "*job_option check:on" - true_command "*job_option check:on" - false_command "*job_option check:off" - } - - frame { - position 1 +6 - size 48 12 - text "MARC INPUT FILE" - border_width 1 - border_color black - - group { - - label { - position 0 4 - size 9 4 - text "VERSION" - border_width 1 - border_color black - } - - roller { - position +9 = - size 14 4 - nvalues 27 - nvisible 27 - texts "DEFAULT" -#if 0 - "2019" -#endif - "2018.1" - "2018" - "2017.1" - "2017" - "2016" - "2015" - "2014.2" - "2014.1" - "2014" - "2013.1" - "2013" - "2012" - "2011" - "2010.2" - "2010" - "2008" - "2007" - "2005R3" - "2005" - "2003" - "2001" - "2000" -#if 0 - "8" -#endif - "K7" - "K6.2" - "K5" - "K4" - help job_param_version - rollers "job_input_version_default" -#if 0 - "job_input_version_2019" -#endif - "job_input_version_2018.1" - "job_input_version_2018" - "job_input_version_2017.1" - "job_input_version_2017" - "job_input_version_2016" - "job_input_version_2015" - "job_input_version_2014.2" - "job_input_version_2014.1" - "job_input_version_2014" - "job_input_version_2013.1" - "job_input_version_2013" - "job_input_version_2012" - "job_input_version_2011" - "job_input_version_2010.2" - "job_input_version_2010" - "job_input_version_2008" - "job_input_version_2007" - "job_input_version_2005r3" - "job_input_version_2005" - "job_input_version_2003" - "job_input_version_2001" - "job_input_version_2000" -#if 0 - "job_input_version_8" -#endif - "job_input_version_k7" - "job_input_version_k6" - "job_input_version_k5" - "job_input_version_k4" - commands "*job_option version:default" -#if 0 - "*job_option version:2019" -#endif - "*job_option version:2018.1" - "*job_option version:2018" - "*job_option version:2017.1" - "*job_option version:2017" - "*job_option version:2016" - "*job_option version:2015" - "*job_option version:2014.2" - "*job_option version:2014.1" - "*job_option version:2014" - "*job_option version:2013.1" - "*job_option version:2013" - "*job_option version:2012" - "*job_option version:2011" - "*job_option version:2010.2" - "*job_option version:2010" - "*job_option version:2008" - "*job_option version:2007" - "*job_option version:2005r3" - "*job_option version:2005" - "*job_option version:2003" - "*job_option version:2001" - "*job_option version:2000" -#if 0 - "*job_option version:8" -#endif - "*job_option version:k7" - "*job_option version:k6" - "*job_option version:k5" - "*job_option version:k4" - visibles "job_allows_input_version_default" -#if 0 - "job_allows_input_version_2019" -#endif - "job_allows_input_version_2018.1" - "job_allows_input_version_2018" - "job_allows_input_version_2017.1" - "job_allows_input_version_2017" - "job_allows_input_version_2016" - "job_allows_input_version_2015" - "job_allows_input_version_2014.2" - "job_allows_input_version_2014.1" - "job_allows_input_version_2014" - "job_allows_input_version_2013.1" - "job_allows_input_version_2013" - "job_allows_input_version_2012" - "job_allows_input_version_2011" - "job_allows_input_version_2010.2" - "job_allows_input_version_2010" - "job_allows_input_version_2008" - "job_allows_input_version_2007" - "job_allows_input_version_2005r3" - "job_allows_input_version_2005" - "job_allows_input_version_2003" - "job_allows_input_version_2001" - "job_allows_input_version_2000" -#if 0 - "job_allows_input_version_8" -#endif - "job_allows_input_version_k7" - "job_allows_input_version_k6" - "job_allows_input_version_k5" - "job_allows_input_version_k4" - } - -# see also job_common.ms -# see also the RUN JOB popmenu in this file - - label { - position +14 = - size 7 4 - text "STYLE" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 3 - texts "TABLE-DRIVEN" - "MULTI-PHYSICS" - "OLD" - rollers "job_input_style_table_driven" - "job_input_style_multi_physics" - "job_input_style_old" - commands "*job_option input_style:new *job_option input_physics_style:old" - "*job_option input_physics_style:new *job_option input_style:new" - "*job_option input_style:old *job_option input_physics_style:old" - visibles "job_allows_input_style_table_driven" - "job_allows_input_style_multi_physics" - "job_allows_input_style_old" - help job_option_input_style - } - - toggle { - position 0 +4 - size 24 4 - text "EXTENDED PRECISION" - help job_run_precision - toggle "*job_option inp_file_prec:extended" - true_command "*job_option inp_file_prec:extended" - false_command "*job_option inp_file_prec:normal" - } - toggle { - position +24 = - size 24 4 - text "INCLUDE UNUSED TABLES" - toggle "*job_option input_file_tables:all" - true_command "*job_option input_file_tables:all" - false_command "*job_option input_file_tables:used" - } - } - } - - button { - position 1 +14 - size 24 4 - text "SCRATCH DIRECTORY" - settext $directory_browser_label "JOB SCRATCH DIRECTORY" - set $directory_browser_command "*job_scratch_directory" - browser directory_browser - help job_scratch_directory - } - - button { - position +24 = - size 24 4 - text "CLEAR" - command "*job_clear_scratch_directory" - visible job_scratch_directory - } - - text { - position 1 +4 - size 48 4 - display job_scratch_dir - command "*job_scratch_directory" - } - -#ifdef DCOM - toggle { - position 1 +6 - size 8 4 - text "\{DCOM}" - toggle "*job_option dcom:on" - help job_run_dcom - true_command "*job_option dcom:on" - false_command "*job_option dcom:off" - visible win32_available - } - - button { - position +8 = - size 12 4 - text "HOSTNAME" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } - - text job_dcom_hostname { - position +12 = - size 28 4 - display "job_dcom_hostname" - command "*job_dcom_hostname" - visible "and(win32_available, *job_option dcom:on)" - } -#endif - - button { - position 1 +6 - size 24 4 - text "TITLE" - popmenu job_title_pm - command "*job_title" - } - - button { - position +24 = - size 24 4 - text "SAVE MODEL" - command "*save_model" - } - - button { - position +4 +6 - size 20 4 - text "WRITE INPUT FILE" - command "*job_write_input" - } - - button { - position = +4 - size 20 4 - text "EDIT INPUT FILE" - command "*job_edit_input" - } - - popdown { - position 1 +5 - size 20 6 - text "SUBMIT 1" - command "*submit_job 1 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 1" - command "*execute_job 1 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 2" - command "*submit_job 2 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 2" - command "*execute_job 2 *monitor_job" - } - - popdown { - position -28 +6 - size 20 6 - text "SUBMIT 3" - command "*submit_job 3 *monitor_job" - } - - popdown { - position +28 = - size 20 6 - text "EXECUTE 3" - command "*execute_job 3 *monitor_job" - } - - popdown { - position 19 +8 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 -#ifdef DCOM - size 50 100 -#else - size 50 94 -#endif - background_color body - border_width 1 - border_color border - buffering single - } - - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -popmenu job_exit_msg_pm { - - text "EXIT MESSAGE" - - group { - - - - text { - position 1 5 - size 84 74 - multiline - readonly - display "job_exit_msg" - } - - popdown { - position 37 +76 - size 12 8 - text "OK" - } - } - - window { - parent mentat - origin 38 8 - size 86 90 - background_color body - border_width 1 - border_color border - buffering single - } - - mode dialog -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_run_parallelization_pm { - - text "SOLVER/PARALLELIZATION" - - group { - layout vbox - frame { - position 0 0 - size 42 8 - group { - - label { - position 0 0 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 36 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 36 4 - display job_class_label - } - } - } - frame { - position 0 8 - size 42 20 - group job_ddm_gr - text "DOMAIN DECOMPOSITION" - border_width 1 - border_color black - } - - frame { - position 0 +20 - size 42 13 - group job_assem_recov_gr - text "ASSEMBLY AND RECOVERY" - border_width 1 - border_color black - } - - frame { - position 0 +14 - size 42 31 - group job_parallel_matrix_solver_gr - text "MATRIX SOLVER" - border_width 1 - border_color black - } - - frame { - position 0 +32 - size 42 28 - group job_parallel_env_gr - text "PARALLELIZATION ENVIRONMENT" - border_width 1 - border_color black - visible "or(*job_option parallel:on, \ - solver_multi_procs)" - } - frame { - position 15 +30 - size 42 8 - group { - layout hbox - - spacer { - stretch 1 - } - popdown { - position 15 0 - size 12 8 - text "OK" - } - spacer { - stretch 1 - } - } - } - - spacer { - spacing 2 - stretch 1 - } - } - - window { - parent mentat - origin 38 1 - size 60 119 - background_color body - border_width 1 - border_color border - buffering single - } - mode permanent -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_gr { - - toggle { - position 1 4 - size 42 4 - text "USE \{DDM}" - toggle "*job_option parallel:on" - help job_run_ddm_use - true_command "*job_option parallel:on" - false_command "*job_option parallel:off" - active "and(not(job_solver_it_ext),\ - not(job_solver_mixed_direct_iterative))" - } - - frame { - position = +5 - size 42 4 - group job_ddm_use_gr - visible "*job_option parallel:on" - } -} - -group job_ddm_use_gr { - layout vbox - frame{ - position 0 0 - size 30 4 - group { - layout hbox - label { - position 0 0 - size 12 4 - text "DECOMPOSITION IN" - help job_run_ddm_generator - } - oneonly{ - position +12 = - size 8 4 - text "MARC" - oneonly "*job_option ddm_generator:fea_solver" - command "*job_option ddm_generator:fea_solver" - help job_run_ddm_generator - } - oneonly{ - position +12 = - size 8 4 - text "MENTAT" - oneonly "*job_option ddm_generator:preprocessor" - command "*job_option ddm_generator:preprocessor" - help job_run_ddm_generator - } - } - } - - frame { - position 0 +5 - size 44 8 - group job_ddm_fea_solver_gr - visible "*job_option ddm_generator:fea_solver" - } - - frame { - position = = - size 44 8 - group job_ddm_preprocessor_gr - visible "*job_option ddm_generator:preprocessor" - } - - frame{ - position 0 +5 - size 40 4 - group{ - layout hbox - text { - position 0 0 - size 22 4 - text "Single Input File" - readonly - visible "*job_option ddm_generator:fea_solver" - } - - roller { - position = = - size 22 4 - nvalues 2 - texts "MULTIPLE INPUT FILES" - "SINGLE INPUT FILE" - roller "job_option ddm_single_input" - commands "*job_option ddm_single_input:off" - "*job_option ddm_single_input:on" - visible "*job_option ddm_generator:preprocessor" - help job_run_ddm_single_input - } - - roller { - position +23 = - size 21 4 - nvalues 2 - texts "MULTIPLE POST FILES" - "SINGLE POST FILE" - roller "job_option ddm_single_post" - commands "*job_option ddm_single_post:off" - "*job_option ddm_single_post:on" - help job_run_ddm_single_post - } - } - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_fea_solver_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - help job_param - } - - text { - position +10 = - size 4 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 0 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 18 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - button { - position +18 = - size 12 4 - text "ADV. SETTINGS" - popmenu job_ddm_fea_solver_pm - } -} - - - - -#-------------------------------------------------------------------------------------------------- -popmenu job_ddm_fea_solver_pm { - - text "JOB PARALLELIZATION" - - group { - units 32 120 - - - label { - position 0 5 - size 6 4 - text "NAME" - } - - display { - position +6 = - size 26 4 - display "job_name" - } - - label { - position 0 +4 - size 6 4 - text "TYPE" - } - - display { - position +6 = - size 26 4 - display job_class_label - } - - frame { - - position 0 +9 - size 32 76 - text "ADVANCED DECOMPOSITION IN MARC" - border_width 1 - border_color black - - group { - - label { - position 1 4 - size 16 4 - text "# DOMAINS" - help job_param - } - - text { - position +16 = - size 14 4 - display "job_param_value_ndomains" - command "*job_param ndomains" - } - - label { - position 1 +4 - size 7 4 - text "METHOD" - border_width 1 - border_color black - } - - roller { - position +7 = - size 23 4 - nvalues 7 - texts "METIS BEST" - "METIS ELEMENT" - "METIS NODE" - "REC. COORD. BISECTION" - "VECTOR" - "RADIAL" - "ANGULAR" - help set_job_decomp_type - rollers "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - commands "*job_option ddm_method:metis_best" - "*job_option ddm_method:metis_element_based" - "*job_option ddm_method:metis_node_based" - "*job_option ddm_method:recur_coord_bisect" - "*job_option ddm_method:vector" - "*job_option ddm_method:radial" - "*job_option ddm_method:angular" - } - - frame { - position 1 +5 - size 30 20 - group job_ddm_direction_gr - visible "or(*job_option ddm_method:vector, \ - *job_option ddm_method:radial, \ - *job_option ddm_method:angular)" - } - - toggle { - position 1 +21 - size 30 4 - text "DOMAIN ISLAND REMOVAL" - toggle "*job_option ddm_island_removal:on" - true_command "*job_option ddm_island_removal:on" - false_command "*job_option ddm_island_removal:off" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "GRAPH" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "COARSE" - "FINE" - help ddm_decomp_coarse_graph - rollers "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - commands "*job_option ddm_graph:coarse" - "*job_option ddm_graph:fine" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - } - - label { - position 1 +4 - size 15 4 - border_width 1 - border_color black - text "QUADRATIC ELEMENTS" - } - - roller { - position +15 = - size 15 4 - nvalues 2 - texts "GENUINE" - "LINEARIZED" - help job_run_ddm_decomp_linearized - rollers "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - commands "*job_option ddm_quadr_elems:genuine" - "*job_option ddm_quadr_elems:linearized" - } - - label { - position 1 +5 - size 15 4 - text "ELEMENT WEIGHT FACTOR" - help job_param - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_elem_weight_factor" - command "*job_param ddm_elem_weight_factor" - help job_run_ddm_decomp_element_weight_factor - } - - toggle { - position 1 +5 - size 30 4 - text "DETECT CONTACT" - toggle "*job_option ddm_detect_contact:on" - true_command "*job_option ddm_detect_contact:on" - false_command "*job_option ddm_detect_contact:off" - visible "or(*job_option ddm_method:metis_best, \ - *job_option ddm_method:metis_element_based, \ - *job_option ddm_method:metis_node_based)" - help job_run_ddm_decomp_detect_contact - } - - label { - position = +5 - size 15 4 - text "CONTACT TOLERANCE" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - command "*set_ddm_contact_tolerance" - display "job_param_value_ddm_contact_tolerance" - command "*job_param ddm_contact_tolerance" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_tolerance - } - - label { - position -15 +4 - size 15 4 - text "CONTACT CONSTR FACTOR" - visible "*job_option ddm_detect_contact:on" - } - - text { - position +15 = - size 15 4 - display "job_param_value_ddm_contact_constr_factor" - command "*job_param ddm_contact_constr_factor" - visible "*job_option ddm_detect_contact:on" - help job_run_ddm_decomp_contact_constraint_factor - } - } - } - - popdown { - position 0 +77 - size 32 8 - text "OK" - } - } - mode permanent -} # job_ddm_fea_solver_pm - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_direction_gr { - - button { - position 0 0 - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "*job_option ddm_method:vector" - } - - button { - position = = - size 15 4 - text "DIRECTION" - command "*job_vector ddm_sort_direction_x" - visible "not(*job_option ddm_method:vector)" - } - - button { - position +15 = - size 15 4 - text "FROM / TO" - command "*job_vector_from_to ddm_sort_direction_x" - } - - text { - position -15 +4 - size 10 4 - command "*job_param ddm_sort_direction_x" - display "job_param_value_ddm_sort_direction_x" - help ddm_job_decomp_user_direction_x - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_y" - display "job_param_value_ddm_sort_direction_y" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_direction_z" - display "job_param_value_ddm_sort_direction_z" - } - - frame { - position 0 +4 - size 30 8 - group job_ddm_sort_point_gr - visible "not(*job_option ddm_method:vector)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_sort_point_gr { - - label { - position 0 0 - size 14 4 - border_width 1 - border_color black - text "POINT ON AXIS" - } - - roller { - position +14 = - size 10 4 - nvalues 2 - texts "DEFAULT" - "USER" - roller "job_option ddm_sort_point" - commands "*job_option ddm_sort_point:default" - "*job_option ddm_sort_point:user" - } - - button { - position +10 = - size 6 4 - text "SET" - command "*job_position ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position 0 +4 - size 10 4 - command "*job_param ddm_sort_point_x" - display "job_param_value_ddm_sort_point_x" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_y" - display "job_param_value_ddm_sort_point_y" - visible "*job_option ddm_sort_point:user" - } - - text { - position +10 = - size 10 4 - command "*job_param ddm_sort_point_z" - display "job_param_value_ddm_sort_point_z" - visible "*job_option ddm_sort_point:user" - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_ddm_preprocessor_gr { - - label { - position 0 0 - size 10 4 - text "# DOMAINS" - border_width 1 - border_color black - } - - integer { - position +10 = - size 4 4 - display valid_domains - } - - button { - position 0 +4 - size 30 4 - text "USER DOMAINS" - popmenu domains_pm - help job_run_ddm_user_domains - } -} - - - - -#-------------------------------------------------------------------------------------------------- -group job_assem_recov_gr { - - toggle { - position 1 +4 - size 30 4 - text "MULTIPLE THREADS" - true_command "*job_option assem_recov_multi_threading:on" - false_command "*job_option assem_recov_multi_threading:off" - toggle "*job_option assem_recov_multi_threading:on" - } - - label { - position = +4 - size 12 4 - text "# THREADS" - visible "*job_option assem_recov_multi_threading:on" - } - - text { - position +12 = - size 4 4 - display "job_param_value_assem_recov_nthreads" - command "*job_param assem_recov_nthreads" - visible "*job_option assem_recov_multi_threading:on" - } - - label { - position +4 = - size 10 4 - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - } - - display { - position +12 = - size 4 4 - display "job_assem_recov_nthreads_dom" - visible "and(*job_option assem_recov_multi_threading:on, \ - *job_option parallel:on)" - } - spacer{ - stretch 2 - } - -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_matrix_solver_gr { - layout vbox - frame { - position 1 0 - size 36 31 - group { - layout hbox - label { - position 3 4 - size 12 4 - text "SOLUTION" - border_width 1 - border_color black - } - oneonly { - position +12 = - size 12 4 - text "SYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_off" - command "*job_option solver_nonsym:off" - } - oneonly { - position +12 = - size 12 4 - text "NONSYMMETRIC" - help job_param_solver_method - oneonly "job_nonsym_on" - command "*job_option solver_nonsym:on" - } - spacer { - stretch 1 - } - } - } - - frame { - position 1 +5 - size 42 23 - group matrix_solver_gr - help job_param_solver - } - - frame { - position +1 = - size 42 4 - group job_run_solver_ddm_opts_gr - visible "*job_option parallel:on" - } - - frame { - position 1 +23 - size 42 8 - group job_solver_multi_procs_gr - visible solver_allows_multi_procs - } - - frame { - position = = - size 42 8 - group job_solver_multi_threads_gr - visible solver_allows_multi_threads - } - - frame { - position 1 +9 - size 42 8 - group job_solver_gpu_gr - visible "and(job_solver_mfront_sparse,job_nonsym_off)" - } - -} - - -#-------------------------------------------------------------------------------------------------- -group job_run_solver_ddm_opts_gr { - - button { - position 0 0 - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options -# see also job_common.ms! - visible "not(or(job_solver_it_sparse, \ - job_solver_it_ext, \ - job_solver_mixed_direct_iterative, \ - job_solver_pardiso,\ - job_solver_mumps))" - } - button { - position = = - size 14 4 - text "\{DDM} OPTIONS" - popmenu ddm_options_mumps - visible "job_solver_mumps" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_gr { - frame { - position 0 0 - size 42 8 - group job_solver_multi_procs_parallel_off_gr - visible "*job_option parallel:off" - } - - frame { - position = = - size 42 8 - group job_solver_multi_procs_parallel_on_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - true_command "*job_option nsolver_procs_serial:on" - false_command "*job_option nsolver_procs_serial:off" - toggle "*job_option nsolver_procs_serial:on" - help job_run_multithreading - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - visible "*job_option nsolver_procs_serial:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - visible "*job_option nsolver_procs_serial:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_procs_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE SOLVER PROCESSES" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +2 +4 - size 14 4 - text "# PROCESSES" - border_width 1 - border_color black - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - help job_run_multithreading - rollers "*job_option nsolver_procs_ddm:automatic" - "*job_option nsolver_procs_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_nsolver_procs_ddm_automatic_gr - visible "*job_option nsolver_procs_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_nsolver_procs_ddm_user_gr - visible "*job_option nsolver_procs_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_nsolver_procs_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nsolver_procs" - command "*job_param nsolver_procs" - } -} - -group job_solver_multi_threads_gr { - frame { - position 0 0 - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_off_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:off)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_mfront_sparse_parallel_on_gr - visible "and(job_solver_mfront_sparse,*job_option parallel:on)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_pardiso_parallel_off_gr - visible "and(job_solver_pardiso,*job_option parallel:off)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_pardiso_parallel_on_gr - visible "and(job_solver_pardiso,*job_option parallel:on)" - } - - frame { - position = = - size 46 8 - group job_solver_multi_threads_it_ext_off_gr - visible "and(job_solver_it_ext,*job_option parallel:off)" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option mfront_sparse_multi_threading:on" - true_command "*job_option mfront_sparse_multi_threading:on" - false_command "*job_option mfront_sparse_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option mfront_sparse_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option mfront_sparse_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_mfront_sparse_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position +30 0 - size 12 4 - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - text "PER DOMAIN" - border_width 1 - border_color black - } - - display { - position +12 0 - size 4 4 - display "job_mfront_sparse_nthreads_dom" - visible "and( not(*job_option ddm_precond:direct)\ - *job_option parallel:on)" - } - - label { - position 0 +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option mfront_sparse_multi_threading_ddm:automatic" - "*job_option mfront_sparse_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_automatic_gr - visible "*job_option mfront_sparse_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_mfront_sparse_multi_threads_ddm_user_gr - visible "*job_option mfront_sparse_multi_threading_ddm:user" - } -} -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_mfront_sparse_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - - - -#-------------------------------------------------------------------------------------------------- -group job_solver_gpu_gr { - - toggle { - position 0 0 - size 30 4 - text "USE \{GPU(s)}" - toggle "*job_option solver_use_gpu:on" - true_command "*job_option solver_use_gpu:on" - false_command "*job_option solver_use_gpu:off" - help job_solver_gpu - } - frame{ - position 0 +4 - size 28 4 - group{ - layout hbox - - label { - position 0 0 - size 16 4 - text "\{GPU} SELECTION" - border_width 1 - border_color black - visible "*job_option solver_use_gpu:on" - } - - roller { - position +16 = - size 12 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - rollers "*job_option solver_gpus:automatic" - "*job_option solver_gpus:user" - visible "*job_option solver_use_gpu:on" - help job_solver_gpu - } - - text { - position +12 = - size 12 4 - display job_solver_gpus - command "*clear_job_solver_gpus *job_solver_gpus" - visible "and(*job_option solver_use_gpu:on,*job_option solver_gpus:user)" - } - spacer { - stretch 1 - } - } - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option pardiso_multi_threading:on" - true_command "*job_option pardiso_multi_threading:on" - false_command "*job_option pardiso_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option pardiso_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option pardiso_multi_threading:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_pardiso_parallel_on_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - help job_run_multithreading - toggle true - set $dummy dummy - } - - label { - position = +4 - size 14 4 - text "# THREADS" - border_color black - border_width 1 - } - - roller { - position +14 = - size 14 4 - nvalues 2 - texts "AUTOMATIC" - "USER" - commands "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - help job_run_multithreading - rollers "*job_option pardiso_multi_threading_ddm:automatic" - "*job_option pardiso_multi_threading_ddm:user" - } - - frame { - position +14 = - size 16 4 - group job_pardiso_multi_threads_ddm_automatic_gr - visible "*job_option pardiso_multi_threading_ddm:automatic" - } - - frame { - position = = - size 16 4 - group job_pardiso_multi_threads_ddm_user_gr - visible "*job_option pardiso_multi_threading_ddm:user" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_automatic_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - border_width 1 - border_color black - } - - integer { - position +8 = - size 8 4 - display valid_domains - visible "*job_option ddm_generator:preprocessor" - } - - integer { - position = = - size 8 4 - display "job_param_ndomains" - visible "*job_option ddm_generator:fea_solver" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_pardiso_multi_threads_ddm_user_gr { - - label { - position 0 0 - size 8 4 - text "VALUE" - help job_param - } - - text { - position +8 = - size 8 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_solver_multi_threads_it_ext_off_gr { - - toggle { - position 0 0 - size 30 4 - text "MULTIPLE THREADS" - toggle "*job_option it_ext_multi_threading:on" - true_command "*job_option it_ext_multi_threading:on" - false_command "*job_option it_ext_multi_threading:off" - help job_run_multithreading - } - - label { - position = +4 - size 14 4 - text "# THREADS" - visible "*job_option it_ext_multi_threading:on" - help job_param - } - - text { - position +14 = - size 14 4 - display "job_param_value_nthreads" - command "*job_param nthreads" - visible "*job_option it_ext_multi_threading:on" - } -} - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_gr { - - frame{ - position 0 +4 - size 40 4 - group{ - layout hbox - label{ - position 0 0 - size 8 4 - text "SETUP" - help job_run_ddm_setup - } - oneonly { - position +12 = - size 12 4 - text "SINGLE MACHINE" - oneonly "*job_option parallel_setup:single" - command "*job_option parallel_setup:single" - help job_run_ddm_setup - } - oneonly { - position +8 = - size 12 4 - text "NETWORK" - oneonly "*job_option parallel_setup:network" - command "*job_option parallel_setup:network" - help job_run_ddm_setup - } - - spacer { - stretch 1 - } - } - } - - - frame { - position +1 +5 - size 40 16 - group job_parallel_env_network_gr - visible "*job_option parallel_setup:network" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_gr { - - button { - position 0 0 - size 28 4 - text "HOST FILE" - browser host_file_browser - settext $host_file_browser_label "SELECT HOST FILE" - set $host_file_browser_command "*job_host_file" - help job_host_file - } - - button { - position +28 = - size 8 4 - text "EDIT" - command "*job_edit_host_file" - help job_edit_host_file - visible job_host_file - } - - button { - position +8 = - size 8 4 - text "CLEAR" - command "*job_clear_host_file" - help job_clear_host_file - visible job_host_file - } - - display { - position 0 +4 - size 44 4 - display job_host_file - } - - frame { - position 0 +5 - size 44 9 - group job_parallel_env_network_ddm_gr - visible "*job_option parallel:on" - } -} - - -#-------------------------------------------------------------------------------------------------- -group job_parallel_env_network_ddm_gr { - - toggle { - position 0 0 - size 22 4 - text "COPY INPUT FILE" - toggle "*job_option copy_input_file:on" - true_command "*job_option copy_input_file:on" - false_command "*job_option copy_input_file:off" - help job_host_copy_inputfile - } - - toggle { - position +23 = - size 21 4 - text "COPY POST FILE" - toggle "*job_option copy_post_file:on" - true_command "*job_option copy_post_file:on" - false_command "*job_option copy_post_file:off" - help job_host_copy_inputfile - } - - label { - position 0 +5 - size 10 4 - text "HOSTS" - border_width 1 - border_color black - visible job_usersub_file - } - - roller { - position +10 = - size 18 4 - nvalues 2 - texts "COMPATIBLE" - "INCOMPATIBLE" - roller "job_option network_hosts" - commands "*job_option network_hosts:compatible" - "*job_option network_hosts:incompatible" - help job_host_comp - visible job_usersub_file - } -} - - -#endif diff --git a/installation/mods_MarcMentat/2020/Marc_tools/include_linux64 b/installation/mods_MarcMentat/2020/Marc_tools/include_linux64 index 7d768846a..23e7b589b 100644 --- a/installation/mods_MarcMentat/2020/Marc_tools/include_linux64 +++ b/installation/mods_MarcMentat/2020/Marc_tools/include_linux64 @@ -542,15 +542,15 @@ fi # DAMASK compiler calls: additional flags are in line 2 OpenMP flags in line 3 DFORTLOWMP="$FCOMP -c -O0 -qno-offload -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2019 -DDAMASKVERSION=$DAMASKVERSION \ + -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2020 -DDAMASKVERSION=$DAMASKVERSION \ -qopenmp -qopenmp-threadprivate=compat\ $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" DFORTRANMP="$FCOMP -c -O1 -qno-offload -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2019 -DDAMASKVERSION=$DAMASKVERSION \ + -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2020 -DDAMASKVERSION=$DAMASKVERSION \ -qopenmp -qopenmp-threadprivate=compat\ $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" DFORTHIGHMP="$FCOMP -c -O3 -qno-offload -implicitnone -stand f08 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ - -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2019 -DDAMASKVERSION=$DAMASKVERSION \ + -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMarc4DAMASK=2020 -DDAMASKVERSION=$DAMASKVERSION \ -qopenmp -qopenmp-threadprivate=compat\ $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD" diff --git a/src/DAMASK_Marc.f90 b/src/DAMASK_Marc.f90 index 8537992e8..c295de1ee 100644 --- a/src/DAMASK_Marc.f90 +++ b/src/DAMASK_Marc.f90 @@ -212,8 +212,8 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, & ! Marc common blocks are in fixed format so they have to be reformated to free format (f90) ! Beware of changes in newer Marc versions -#include QUOTE(PASTE(./marc/include/concom,Marc4DAMASK)) ! concom is needed for inc, lovl -#include QUOTE(PASTE(./marc/include/creeps,Marc4DAMASK)) ! creeps is needed for timinc (time increment) +#include QUOTE(PASTE(./Marc/include/concom,Marc4DAMASK)) ! concom is needed for inc, lovl +#include QUOTE(PASTE(./Marc/include/creeps,Marc4DAMASK)) ! creeps is needed for timinc (time increment) logical :: cutBack real(pReal), dimension(6) :: stress diff --git a/src/marc/discretization_marc.f90 b/src/Marc/discretization_Marc.f90 similarity index 100% rename from src/marc/discretization_marc.f90 rename to src/Marc/discretization_Marc.f90 diff --git a/src/marc/include/concom2020 b/src/Marc/include/concom2020 similarity index 100% rename from src/marc/include/concom2020 rename to src/Marc/include/concom2020 diff --git a/src/marc/include/creeps2020 b/src/Marc/include/creeps2020 similarity index 100% rename from src/marc/include/creeps2020 rename to src/Marc/include/creeps2020 diff --git a/src/commercialFEM_fileList.f90 b/src/commercialFEM_fileList.f90 index 97e7520f9..585f242b5 100644 --- a/src/commercialFEM_fileList.f90 +++ b/src/commercialFEM_fileList.f90 @@ -16,7 +16,7 @@ #include "results.f90" #include "geometry_plastic_nonlocal.f90" #include "discretization.f90" -#include "marc/discretization_marc.f90" +#include "Marc/discretization_Marc.f90" #include "material.f90" #include "lattice.f90" #include "phase.f90" diff --git a/src/marc/include/concom2018 b/src/marc/include/concom2018 deleted file mode 100644 index 59b0c6bcb..000000000 --- a/src/marc/include/concom2018 +++ /dev/null @@ -1,427 +0,0 @@ -! common block definition file taken from respective MSC.Marc release and reformated to free format -!*********************************************************************** -! -! File: concom.cmn -! -! MSC.Marc include file -! -integer & - iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva, idyn, idynt,& - ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,& - ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,& - ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,& - itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,& - lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,& - icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,& - isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,& - ibukty, iassum, icnstd, icnstt, kmakmas, imethvp, iradrte, iradrtp, iupdate, iupdatp,& - ncycnt, marmen , idynme, ihavca, ispf, kmini, imixex, largtt, kdoela, iautofg,& - ipshftp, idntrc, ipore, jtablm, jtablc, isnecma, itrnspo, imsdif, jtrnspo, mcnear,& - imech, imecht, ielcmat, ielectt, magnett, imsdift, noplas, jtabls, jactch, jtablth,& - kgmsto , jpzo, ifricsh, iremkin, iremfor, ishearp, jspf, machining, jlshell, icompsol,& - iupblgfo, jcondir, nstcrp, nactive, ipassref, nstspnt, ibeart, icheckmpc, noline, icuring,& - ishrink, ioffsflg, isetoff, ioffsetm,iharmt, inc_incdat, iautspc, ibrake, icbush, istream_input,& - iprsinp, ivlsinp, ifirst_time,ipin_m, jgnstr_glb, imarc_return,iqvcinp, nqvceid, istpnx, imicro1,& - iaxisymm, jbreakglue,iglstif, jfastasm,iwear, iwearcf, imixmeth, ielcmadyn, idinout, igena_meth,& - magf_meth, non_assumed, iredoboudry, ioffsz0,icomplt, mesh_dual, iactrp, mgnewton, iusedens,igsigd0,& - iaem, icosim, inodels, nlharm, iampini, iphasetr, inonlcl, inonlct, iforminp,ispecerror,& - icsprg -dimension :: ideva(60) -integer num_concom -parameter(num_concom=251) -common/marc_concom/& - iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva, idyn, idynt,& - ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,& - ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,& - ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,& - itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,& - lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,& - icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,& - isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,& - ibukty, iassum, icnstd, icnstt, kmakmas, imethvp, iradrte, iradrtp, iupdate, iupdatp,& - ncycnt, marmen, idynme, ihavca, ispf, kmini, imixex, largtt, kdoela, iautofg,& - ipshftp, idntrc, ipore, jtablm, jtablc, isnecma, itrnspo, imsdif, jtrnspo, mcnear,& - imech, imecht, ielcmat, ielectt, magnett, imsdift, noplas, jtabls, jactch, jtablth,& - kgmsto , jpzo, ifricsh, iremkin, iremfor, ishearp, jspf, machining, jlshell, icompsol,& - iupblgfo, jcondir, nstcrp, nactive, ipassref, nstspnt, ibeart, icheckmpc, noline, icuring,& - ishrink, ioffsflg, isetoff, ioffsetm,iharmt, inc_incdat, iautspc, ibrake, icbush, istream_input,& - iprsinp, ivlsinp, ifirst_time,ipin_m, jgnstr_glb, imarc_return,iqvcinp, nqvceid, istpnx, imicro1,& - iaxisymm, jbreakglue,iglstif, jfastasm,iwear, iwearcf, imixmeth, ielcmadyn, idinout, igena_meth,& - magf_meth, non_assumed, iredoboudry, ioffsz0,icomplt, mesh_dual, iactrp, mgnewton, iusedens,igsigd0,& - iaem, icosim, inodels, nlharm, iampini, iphasetr, inonlcl, inonlct, iforminp,ispecerror,& - icsprg -! -! comments of variables: -! -! iacous Control flag for acoustic analysis. Input data. -! iacous=1 modal acoustic analysis. -! iacous=2 harmonic acoustic-structural analysis. -! iasmbl Control flag to indicate that operator matrix should be -! recalculated. -! iautth Control flag for AUTO THERM option. -! ibear Control flag for bearing analysis. Input data. -! icompl Control variable to indicate that a complex analysis is -! being performed. Either a Harmonic analysis with damping, -! or a harmonic electro-magnetic analysis. Input data. -! iconj Flag for EBE conjugate gradient solver (=solver 1, retired) -! Also used for VKI iterative solver. -! icreep Control flag for creep analysis. Input data. -! ideva(60) - debug print out flag -! 1 print element stiffness matrices, mass matrix -! 2 output matrices used in tying -! 3 force the solution of a nonpositive definite matrix -! 4 print info of connections to each node -! 5 info of gap convergence, internal heat generated, contact -! touching and separation -! 6 nodal value array during rezoning -! 7 tying info in CONRAD GAP option, fluid element numbers in -! CHANNEL option -! 8 output incremental displacements in local coord. system -! 9 latent heat output -! 10 stress-strain in local coord. system -! 11 additional info on interlaminar stress -! 12 output right hand side and solution vector -! 13 info of CPU resources used and memory available on NT -! 14 info of mesh adaption process, 2D outline information -! info of penetration checking for remeshing -! save .fem files after afmesh3d meshing -! 15 surface energy balance flag -! 16 print info regarding pyrolysis -! 17 print info of "streamline topology" -! 18 print mesh data changes after remeshing -! 19 print material flow stress data read in from *.mat file -! if unit flag is on, print out flow stress after conversion -! 20 print information on table input -! 21 print out information regarding kinematic boundary conditions -! 22 print out information regarding dist loads, point loads, film -! and foundations -! 23 print out information about automatic domain decomposition -! 24 print out iteration information in SuperForm status report file -! 25 print out information for ablation -! 26 print out information for films - Table input -! 27 print out the tying forces -! 28 print out for CASI solver, convection, -! 29 DDM single file debug printout -! 30 print out cavity debug info -! 31 print out welding related info -! 32 prints categorized DDM memory usage -! 33 print out the cutting info regarding machining feature -! 34 print out the list of quantities which can be defined via a table -! and for each quantity the supported independent variables -! 35 print out detailed coupling region info -! 36 print out solver debug info level 1 (Least Detailed) -! 37 print out solver debug info level 1 (Medium Detailed) -! 38 print out solver debug info level 1 (Very Detailed) -! 39 print detailed memory allocation info -! 40 print out marc-adams debug info -! 41 output rezone mapping post file for debugging -! 42 output post file after calling oprofos() for debugging -! 43 debug printout for vcct -! 44 debug printout for progressive failure -! 45 print out automatically generated midside node coordinates (arecrd) -! 46 print out message about routine and location, where the ibort is raised (ibort_inc) -! 47 print out summary message of element variables on a -! group-basis after all the automatic changes have been -! made (em_ellibp) -! 48 Automatically generate check results based on max and min vals. -! These vals are stored in the checkr file, which is inserted -! into the *dat file by the generate_check_results script from /marc/tools -! 49 Automatically generate check results based on the real calculated values -! at the sppecified check result locations. -! These vals are stored in the checkr file, which is inserted -! into the *dat file by the update_check_results script from /marc/tools -! 50 generate a file containing the resistance or capacity matrix; -! this file can be used to compare results with a reference file -! 51 print out detailed information for segment-to-segment contact -! 52 print out detailed relative displacement information -! for uniaxial sliding contact -! 53 print out detailed sliding direction information for -! uniaxial sliding contact -! 54 print out detailed information for edges attached to a curve -! 55 print information related to viscoelasticity calculations -! 56 print out detailed information for element coloring for multithreading -! 57 print out extra overheads due to multi-threading. -! These overhead includes (i) time and (ii) memory. -! The memory report will be summed over all the children. -! -! -! 58 debug output for ELSTO usage -! -! idyn Control flag for dynamics. Input data. -! 1 = eigenvalue extraction and / or modal superposition -! 2 = Newmark Beta and Single Step Houbolt (ssh with idynme=1) -! 3 = Houbolt -! 4 = Central difference -! 5 = Newer central difference -! idynt Copy of idyn at begining of increment -! ielas Control flag for ELASTIC analysis. Input data. -! Set by user or automatically turned on by Fourier option. -! Implies that each load case is treated separately. -! In Adaptive meshing analysis , forces re-analysis until -! convergence obtained. -! Also seriously misused to indicate no convergence. -! = 1 elastic option with fourier analysis -! = 2 elastic option without fourier analysis -! =-1 no convergence in recycles or max # increments reached -! Set to 1 if ELASTIC or SUBSTRUC parameter cards are used, -! or if fourier option is used. -! Then set to 2 if not fourier analysis. -! ielcma Control flag for electromagnetic analysis. Input data. -! ielcma = 1 Harmonic formulation -! ielcma = 2 Transient formulation -! ielect Control flag for electrostatic option. Input data. -! iform Control flag indicating that contact will be performed. -! ifour Control flag for Fourier analysis. -! 0 = Odd and even terms. -! 1 = symmetric (cosine) terms -! 2 = antisymmetric (sine) terms. -! iharm Control flag to indicate that a harmonic analysis will -! be performed. May change between passes. -! ihcps Control flag for coupled thermal - stress analysis. -! iheat Control flag for heat transfer analysis. Input data. -! iheatt Permanent control flag for heat transfer analysis. -! Note in coupled analysis iheatt will remain as one, -! but iheat will be zero in stress pass. -! ihresp Control flag to indicate to perform a harmonic subincrement. -! ijoule Control flag for Joule heating. -! ilem Control flag to determin which vector is to be transformed. -! Control flag to see where one is: -! ilem = 1 - elem.f -! ilem = 2 - initst.f -! ilem = 3 - pressr.f -! ilem = 3 - fstif.f -! ilem = 4 - jflux.f -! ilem = 4 - strass.f -! ilem = 5 - mass.f -! ilem = 5 - osolty.f -! ilnmom Control flag for soil - pore pressure calculation. Input data. -! ilnmom = 0 - perform only pore pressure calculation. -! = 1 - couples pore pressure - displacement analysis -! iloren Control flag for DeLorenzi J-Integral evaluation. Input data. -! inc Increment number. -! incext Control flag indicating that currently working on a -! subincrement. -! Could be due to harmonics , damping component (bearing), -! stiffness component (bearing), auto therm creep or -! old viscoplaticity -! incsub Sub-increment number. -! ipass Control flag for which part of coupled analysis. -! ipass = -1 - reset to base values -! ipass = 0 - do nothing -! ipass = 1 - stress part -! ipass = 2 - heat transfer part -! iplres Flag indicating that either second matrix is stored. -! dynamic analysis - mass matrix -! heat transfer - specific heat matrix -! buckle - initial stress stiffness -! ipois Control flag indicating Poisson type analysis -! ipois = 1 for heat transfer -! = 1 for heat transfer part of coupled -! = 1 for bearing -! = 1 for electrostatic -! = 1 for magnetostatic -! ipoist Permanent copy of ipois. In coupled analysis , ipois = 0 -! in stress portion, yet ipoist will still =1. -! irpflo global flag for rigid plastic flow analysis -! = 1 eularian formulation -! = 2 regular formulation; rigid material present in the analysis - -! ismall control flag to indicate small displacement analysis. input data. -! ismall = 0 - large disp included. -! ismall = 1 - small displacement. -! the flag is changing between passes. -! ismalt permanent copy of ismall . in heat transfer portion of -! coupled analysis ismall =0 , but ismalt remains the same. -! isoil control flag indicating that soil / pore pressure -! calculation . input data. -! ispect control flag for response spectrum calculation. input data. -! ispnow control flag to indicate to perform a spectrum response -! calculation now. -! istore store stresses flag. -! istore = 0 in elem.f and if first pass of creep -! convergence checking in ogetst.f -! or harmonic analysis or thruc.f if not -! converged. -! iswep control flag for eigenvalue analysis. -! iswep=1 - go do extraction process -! ithcrp control flag for auto therm creep option. input data. -! itherm control flag for either temperature dependent material -! properties and/or thermal loads. -! iupblg control flag for follower force option. input data. -! iupdat control flag for update lagrange option for current element. -! jacflg control flag for lanczos iteration method. input data. -! jel control flag indicating that total load applied in -! increment, ignore previous solution. -! jel = 1 in increment 0 -! = 1 if elastic or fourier -! = 1 in subincrements with elastic and adaptive -! jparks control flag for j integral by parks method. input data. -! largst control flag for finite strain plasticity. input data. -! lfond control variable that indicates if doing elastic -! foundation or film calculation. influences whether -! this is volumetric or surface integration. -! loadup control flag that indicates that nonlinearity occurred -! during previous increment. -! loaduq control flag that indicates that nonlinearity occurred. -! lodcor control flag for switching on the residual load correction. -! notice in input stage lodcor=0 means no loadcor, -! after omarc lodcor=1 means no loadcor -! lovl control flag for determining which "overlay" is to -! be called from ellib. -! lovl = 1 omarc -! = 2 oaread -! = 3 opress -! = 4 oasemb -! = 5 osolty -! = 6 ogetst -! = 7 oscinc -! = 8 odynam -! = 9 opmesh -! = 10 omesh2 -! = 11 osetz -! = 12 oass -! = 13 oincdt -! = 14 oasmas -! = 15 ofluas -! = 16 ofluso -! = 17 oshtra -! = 18 ocass -! = 19 osoltc -! = 20 orezon -! = 21 otest -! = 22 oeigen -! lsub control variable to determine which part of element -! assembly function is being done. -! lsub = 1 - no longer used -! = 2 - beta* -! = 3 - cons* -! = 4 - ldef* -! = 5 - posw* -! = 6 - theta* -! = 7 - tmarx* -! = 8 - geom* -! magnet control flag for magnetostatic analysis. input data. -! ncycle cycle number. accumulated in osolty.f -! note first time through oasemb.f , ncycle = 0. -! newtnt control flag for permanent copy of newton. -! newton iteration type. input data. -! newton : = 1 full newton raphson -! 2 modified newton raphson -! 3 newton raphson with strain correct. -! 4 direct substitution -! 5 direct substitution followed by n.r. -! 6 direct substitution with line search -! 7 full newton raphson with secant initial stress -! 8 secant method -! 9 full newton raphson with line search -! noshr control flag for calculation interlaminar shears for -! elements 22,45, and 75. input data. -!ees -! -! jactch = 1 or 2 if elements are activated or deactivated -! = 3 if elements are adaptively remeshed or rezoned -! = 0 normally / reset to 0 when assembly is done -! ifricsh = 0 call to fricsh in otest not needed -! = 1 call to fricsh (nodal friction) in otest needed -! iremkin = 0 remove deactivated kinematic boundary conditions -! immediately - only in new input format (this is default) -! = 1 remove deactivated kinematic boundary conditions -! gradually - only in new input format -! iremfor = 0 remove force boundary conditions immediately - -! only in new input format (this is default) -! = 1 remove force boundary conditions gradually - -! only in new input format (this is default) -! ishearp set to 1 if shear panel elements are present in the model -! -! jspf = 0 not in spf loadcase -! > 0 in spf loadcase (jspf=1 during first increment) -! machining = 1 if the metal cutting feature is used, for memory allocation purpose -! = 0 (default) if no metal cutting feature required -! -! jlshell = 1 if there is a shell element in the mesh -! icompsol = 1 if there is a composite solid element in the mesh -! iupblgfo = 1 if follower force for point loads -! jcondir = 1 if contact priority option is used -! nstcrp = 0 (default) steady state creep flag (undocumented feature. -! if not 0, turns off special ncycle = 0 code in radial.f) -! nactive = number of active passes, if =1 then it's not a coupled analysis -! ipassref = reference ipass, if not in a multiphysics pass ipass=ipassref -! icheckmpc = value of mpc-check parameter option -! noline = set to 1 in osolty if no line seacrh should be done in ogetst -! icuring = set to 1 if the curing is included for the heat transfer analysis. -! ishrink = set to 1 if shrinkage strain is included for mechancial analysis. -! ioffsflg = 1 for small displacement beam/shell offsets -! = 2 for large displacement beam/shell offsets -! isetoff = 0 - do not apply beam/shell offsets -! = 1 - apply beam/shell offsets -! ioffsetm = min. value of offset flag -! iharmt = 1 global flag if a coupled analysis contains an harmonic pass -! inc_incdat = flag to record increment number of a new loadcase in incdat.f -! iautspc = flag for AutoSPC option -! ibrake = brake squeal in this increment -! icbush = set to 1 if cbush elements present in model -! istream_input = set to 1 for streaming input calling Marc as library -! iprsinp = set to 1 if pressure input, introduced so other variables -! such as h could be a function of pressure -! ivlsinp = set to 1 if velocity input, introduced so other variables -! such as h could be a function of velocity -! ipin_m = # of beam element with PIN flag -! jgnstr_glb = global control over pre or fast integrated composite shells -! imarc_return = Marc return flag for streaming input control -! iqvcimp = if non-zero, then the number of QVECT boundary conditions -! nqvceid = number of QVECT boundary conditions, where emisivity/absorbtion id entered -! istpnx = 1 if to stop at end of increment -! imicro1 = 1 if micro1 interface is used -! iaxisymm = set to 1 if axisymmetric analysis -! jbreakglue = set to 1 if breaking glued option is used -! iglstif = 1 if ddm and global stiffness matrix formed (sgi solver 6 or solver9) -! jfastasm = 1 do fast assembly using SuperForm code -! iwear = set to 1 if wear model, set to 2 if wear model and coordinates updated -! iwearcf = set to 1 to store nodal coefficient of friction for wear calculation -! imixmeth = set=1 then use nonlinear mixture material - allocate memory -! ielcmadyn = flag for magnetodynamics -! 0 - electromagnetics using newmark beta -! 1 - transient magnetics using backward euler -! idinout = flag to control if inside out elements should be deactivated -! igena_meth = 0 - generalized alpha parameters depend on whether or not contact -! is flagged (dynamic,7) -! 10 - generalized alpha parameters are optimized for a contact -! analysis (dynamic,8) -! 11 - generalized alpha parameters are optimized for an analysis -! without contact (dynamic,8) -! magf_meth = - Method to compute force in magnetostatic - structural -! = 1 - Virtual work method based on finite difference for the force computation -! = 2 - Maxwell stress tensor -! = 3 - Virtual work method based on local derivative for the force computation -! non_assumed = 1 no assumed strain formulation (forced) -! iredoboudry set to 1 if contact boundary needs to be recalculated -! ioffsz0 = 1 if composite are used with reference position.ne.0 -! icomplt = 1 global flag if a coupled analysis contains an complex pass -! mesh_dual = 1 two independent meshes are used in magnetodynamic/thermal/structural -! one for magnetodynamic and the other for the remaining passes -! iactrp = 1 in an analysis with global remeshing, include inactive -! rigid bodies on post file -! mgnewton = 1 Use full Newton Raphson iteration for magnetostatic pass -! -! iusedens > 0 if mass density is used in the analysis (dynamics, mass dependent loading) -! igsigd0 = 1 set varselem(igsigd) to zero in next oasemb -! iaem = 1 if marc is called from aem (0 - off - default) -! icosim = 1 if marc is used in co-simulation software (ADAMS-MARC) -! inodels = 1 nodal integration elements 239/240/241 present -! nlharm = 0 harmonic subincrements are linear -! = 1 harmonic subincrements are nonlinear -! iampini = 0 amplitude of previous harmonic subinc is initial estimate (default) -! = 1 zero amplitude is initial estimate -! iphasetr = 1 phase transformation material model is used -! iforminp flag indicating that contact is switched on via the CONTACT -! option in the input file (as opposed to the case that contact -! is switched on internally due to cyclic symmetry or model -! section creation) -! ispecerror = a+10*b (only for spectrum response analysis with missing mass option) -! a=0 or a=1 (modal shape with non-zero shift) -! b=0 or b=1 (recover with new assembly of stiffness matrix) -! icsprg = set to 1 if spring elements present in model -! -!*********************************************************************** -!$omp threadprivate(/marc_concom/) -!! diff --git a/src/marc/include/concom2018.1 b/src/marc/include/concom2018.1 deleted file mode 100644 index 59b0c6bcb..000000000 --- a/src/marc/include/concom2018.1 +++ /dev/null @@ -1,427 +0,0 @@ -! common block definition file taken from respective MSC.Marc release and reformated to free format -!*********************************************************************** -! -! File: concom.cmn -! -! MSC.Marc include file -! -integer & - iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva, idyn, idynt,& - ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,& - ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,& - ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,& - itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,& - lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,& - icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,& - isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,& - ibukty, iassum, icnstd, icnstt, kmakmas, imethvp, iradrte, iradrtp, iupdate, iupdatp,& - ncycnt, marmen , idynme, ihavca, ispf, kmini, imixex, largtt, kdoela, iautofg,& - ipshftp, idntrc, ipore, jtablm, jtablc, isnecma, itrnspo, imsdif, jtrnspo, mcnear,& - imech, imecht, ielcmat, ielectt, magnett, imsdift, noplas, jtabls, jactch, jtablth,& - kgmsto , jpzo, ifricsh, iremkin, iremfor, ishearp, jspf, machining, jlshell, icompsol,& - iupblgfo, jcondir, nstcrp, nactive, ipassref, nstspnt, ibeart, icheckmpc, noline, icuring,& - ishrink, ioffsflg, isetoff, ioffsetm,iharmt, inc_incdat, iautspc, ibrake, icbush, istream_input,& - iprsinp, ivlsinp, ifirst_time,ipin_m, jgnstr_glb, imarc_return,iqvcinp, nqvceid, istpnx, imicro1,& - iaxisymm, jbreakglue,iglstif, jfastasm,iwear, iwearcf, imixmeth, ielcmadyn, idinout, igena_meth,& - magf_meth, non_assumed, iredoboudry, ioffsz0,icomplt, mesh_dual, iactrp, mgnewton, iusedens,igsigd0,& - iaem, icosim, inodels, nlharm, iampini, iphasetr, inonlcl, inonlct, iforminp,ispecerror,& - icsprg -dimension :: ideva(60) -integer num_concom -parameter(num_concom=251) -common/marc_concom/& - iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva, idyn, idynt,& - ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,& - ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,& - ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,& - itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,& - lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,& - icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,& - isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,& - ibukty, iassum, icnstd, icnstt, kmakmas, imethvp, iradrte, iradrtp, iupdate, iupdatp,& - ncycnt, marmen, idynme, ihavca, ispf, kmini, imixex, largtt, kdoela, iautofg,& - ipshftp, idntrc, ipore, jtablm, jtablc, isnecma, itrnspo, imsdif, jtrnspo, mcnear,& - imech, imecht, ielcmat, ielectt, magnett, imsdift, noplas, jtabls, jactch, jtablth,& - kgmsto , jpzo, ifricsh, iremkin, iremfor, ishearp, jspf, machining, jlshell, icompsol,& - iupblgfo, jcondir, nstcrp, nactive, ipassref, nstspnt, ibeart, icheckmpc, noline, icuring,& - ishrink, ioffsflg, isetoff, ioffsetm,iharmt, inc_incdat, iautspc, ibrake, icbush, istream_input,& - iprsinp, ivlsinp, ifirst_time,ipin_m, jgnstr_glb, imarc_return,iqvcinp, nqvceid, istpnx, imicro1,& - iaxisymm, jbreakglue,iglstif, jfastasm,iwear, iwearcf, imixmeth, ielcmadyn, idinout, igena_meth,& - magf_meth, non_assumed, iredoboudry, ioffsz0,icomplt, mesh_dual, iactrp, mgnewton, iusedens,igsigd0,& - iaem, icosim, inodels, nlharm, iampini, iphasetr, inonlcl, inonlct, iforminp,ispecerror,& - icsprg -! -! comments of variables: -! -! iacous Control flag for acoustic analysis. Input data. -! iacous=1 modal acoustic analysis. -! iacous=2 harmonic acoustic-structural analysis. -! iasmbl Control flag to indicate that operator matrix should be -! recalculated. -! iautth Control flag for AUTO THERM option. -! ibear Control flag for bearing analysis. Input data. -! icompl Control variable to indicate that a complex analysis is -! being performed. Either a Harmonic analysis with damping, -! or a harmonic electro-magnetic analysis. Input data. -! iconj Flag for EBE conjugate gradient solver (=solver 1, retired) -! Also used for VKI iterative solver. -! icreep Control flag for creep analysis. Input data. -! ideva(60) - debug print out flag -! 1 print element stiffness matrices, mass matrix -! 2 output matrices used in tying -! 3 force the solution of a nonpositive definite matrix -! 4 print info of connections to each node -! 5 info of gap convergence, internal heat generated, contact -! touching and separation -! 6 nodal value array during rezoning -! 7 tying info in CONRAD GAP option, fluid element numbers in -! CHANNEL option -! 8 output incremental displacements in local coord. system -! 9 latent heat output -! 10 stress-strain in local coord. system -! 11 additional info on interlaminar stress -! 12 output right hand side and solution vector -! 13 info of CPU resources used and memory available on NT -! 14 info of mesh adaption process, 2D outline information -! info of penetration checking for remeshing -! save .fem files after afmesh3d meshing -! 15 surface energy balance flag -! 16 print info regarding pyrolysis -! 17 print info of "streamline topology" -! 18 print mesh data changes after remeshing -! 19 print material flow stress data read in from *.mat file -! if unit flag is on, print out flow stress after conversion -! 20 print information on table input -! 21 print out information regarding kinematic boundary conditions -! 22 print out information regarding dist loads, point loads, film -! and foundations -! 23 print out information about automatic domain decomposition -! 24 print out iteration information in SuperForm status report file -! 25 print out information for ablation -! 26 print out information for films - Table input -! 27 print out the tying forces -! 28 print out for CASI solver, convection, -! 29 DDM single file debug printout -! 30 print out cavity debug info -! 31 print out welding related info -! 32 prints categorized DDM memory usage -! 33 print out the cutting info regarding machining feature -! 34 print out the list of quantities which can be defined via a table -! and for each quantity the supported independent variables -! 35 print out detailed coupling region info -! 36 print out solver debug info level 1 (Least Detailed) -! 37 print out solver debug info level 1 (Medium Detailed) -! 38 print out solver debug info level 1 (Very Detailed) -! 39 print detailed memory allocation info -! 40 print out marc-adams debug info -! 41 output rezone mapping post file for debugging -! 42 output post file after calling oprofos() for debugging -! 43 debug printout for vcct -! 44 debug printout for progressive failure -! 45 print out automatically generated midside node coordinates (arecrd) -! 46 print out message about routine and location, where the ibort is raised (ibort_inc) -! 47 print out summary message of element variables on a -! group-basis after all the automatic changes have been -! made (em_ellibp) -! 48 Automatically generate check results based on max and min vals. -! These vals are stored in the checkr file, which is inserted -! into the *dat file by the generate_check_results script from /marc/tools -! 49 Automatically generate check results based on the real calculated values -! at the sppecified check result locations. -! These vals are stored in the checkr file, which is inserted -! into the *dat file by the update_check_results script from /marc/tools -! 50 generate a file containing the resistance or capacity matrix; -! this file can be used to compare results with a reference file -! 51 print out detailed information for segment-to-segment contact -! 52 print out detailed relative displacement information -! for uniaxial sliding contact -! 53 print out detailed sliding direction information for -! uniaxial sliding contact -! 54 print out detailed information for edges attached to a curve -! 55 print information related to viscoelasticity calculations -! 56 print out detailed information for element coloring for multithreading -! 57 print out extra overheads due to multi-threading. -! These overhead includes (i) time and (ii) memory. -! The memory report will be summed over all the children. -! -! -! 58 debug output for ELSTO usage -! -! idyn Control flag for dynamics. Input data. -! 1 = eigenvalue extraction and / or modal superposition -! 2 = Newmark Beta and Single Step Houbolt (ssh with idynme=1) -! 3 = Houbolt -! 4 = Central difference -! 5 = Newer central difference -! idynt Copy of idyn at begining of increment -! ielas Control flag for ELASTIC analysis. Input data. -! Set by user or automatically turned on by Fourier option. -! Implies that each load case is treated separately. -! In Adaptive meshing analysis , forces re-analysis until -! convergence obtained. -! Also seriously misused to indicate no convergence. -! = 1 elastic option with fourier analysis -! = 2 elastic option without fourier analysis -! =-1 no convergence in recycles or max # increments reached -! Set to 1 if ELASTIC or SUBSTRUC parameter cards are used, -! or if fourier option is used. -! Then set to 2 if not fourier analysis. -! ielcma Control flag for electromagnetic analysis. Input data. -! ielcma = 1 Harmonic formulation -! ielcma = 2 Transient formulation -! ielect Control flag for electrostatic option. Input data. -! iform Control flag indicating that contact will be performed. -! ifour Control flag for Fourier analysis. -! 0 = Odd and even terms. -! 1 = symmetric (cosine) terms -! 2 = antisymmetric (sine) terms. -! iharm Control flag to indicate that a harmonic analysis will -! be performed. May change between passes. -! ihcps Control flag for coupled thermal - stress analysis. -! iheat Control flag for heat transfer analysis. Input data. -! iheatt Permanent control flag for heat transfer analysis. -! Note in coupled analysis iheatt will remain as one, -! but iheat will be zero in stress pass. -! ihresp Control flag to indicate to perform a harmonic subincrement. -! ijoule Control flag for Joule heating. -! ilem Control flag to determin which vector is to be transformed. -! Control flag to see where one is: -! ilem = 1 - elem.f -! ilem = 2 - initst.f -! ilem = 3 - pressr.f -! ilem = 3 - fstif.f -! ilem = 4 - jflux.f -! ilem = 4 - strass.f -! ilem = 5 - mass.f -! ilem = 5 - osolty.f -! ilnmom Control flag for soil - pore pressure calculation. Input data. -! ilnmom = 0 - perform only pore pressure calculation. -! = 1 - couples pore pressure - displacement analysis -! iloren Control flag for DeLorenzi J-Integral evaluation. Input data. -! inc Increment number. -! incext Control flag indicating that currently working on a -! subincrement. -! Could be due to harmonics , damping component (bearing), -! stiffness component (bearing), auto therm creep or -! old viscoplaticity -! incsub Sub-increment number. -! ipass Control flag for which part of coupled analysis. -! ipass = -1 - reset to base values -! ipass = 0 - do nothing -! ipass = 1 - stress part -! ipass = 2 - heat transfer part -! iplres Flag indicating that either second matrix is stored. -! dynamic analysis - mass matrix -! heat transfer - specific heat matrix -! buckle - initial stress stiffness -! ipois Control flag indicating Poisson type analysis -! ipois = 1 for heat transfer -! = 1 for heat transfer part of coupled -! = 1 for bearing -! = 1 for electrostatic -! = 1 for magnetostatic -! ipoist Permanent copy of ipois. In coupled analysis , ipois = 0 -! in stress portion, yet ipoist will still =1. -! irpflo global flag for rigid plastic flow analysis -! = 1 eularian formulation -! = 2 regular formulation; rigid material present in the analysis - -! ismall control flag to indicate small displacement analysis. input data. -! ismall = 0 - large disp included. -! ismall = 1 - small displacement. -! the flag is changing between passes. -! ismalt permanent copy of ismall . in heat transfer portion of -! coupled analysis ismall =0 , but ismalt remains the same. -! isoil control flag indicating that soil / pore pressure -! calculation . input data. -! ispect control flag for response spectrum calculation. input data. -! ispnow control flag to indicate to perform a spectrum response -! calculation now. -! istore store stresses flag. -! istore = 0 in elem.f and if first pass of creep -! convergence checking in ogetst.f -! or harmonic analysis or thruc.f if not -! converged. -! iswep control flag for eigenvalue analysis. -! iswep=1 - go do extraction process -! ithcrp control flag for auto therm creep option. input data. -! itherm control flag for either temperature dependent material -! properties and/or thermal loads. -! iupblg control flag for follower force option. input data. -! iupdat control flag for update lagrange option for current element. -! jacflg control flag for lanczos iteration method. input data. -! jel control flag indicating that total load applied in -! increment, ignore previous solution. -! jel = 1 in increment 0 -! = 1 if elastic or fourier -! = 1 in subincrements with elastic and adaptive -! jparks control flag for j integral by parks method. input data. -! largst control flag for finite strain plasticity. input data. -! lfond control variable that indicates if doing elastic -! foundation or film calculation. influences whether -! this is volumetric or surface integration. -! loadup control flag that indicates that nonlinearity occurred -! during previous increment. -! loaduq control flag that indicates that nonlinearity occurred. -! lodcor control flag for switching on the residual load correction. -! notice in input stage lodcor=0 means no loadcor, -! after omarc lodcor=1 means no loadcor -! lovl control flag for determining which "overlay" is to -! be called from ellib. -! lovl = 1 omarc -! = 2 oaread -! = 3 opress -! = 4 oasemb -! = 5 osolty -! = 6 ogetst -! = 7 oscinc -! = 8 odynam -! = 9 opmesh -! = 10 omesh2 -! = 11 osetz -! = 12 oass -! = 13 oincdt -! = 14 oasmas -! = 15 ofluas -! = 16 ofluso -! = 17 oshtra -! = 18 ocass -! = 19 osoltc -! = 20 orezon -! = 21 otest -! = 22 oeigen -! lsub control variable to determine which part of element -! assembly function is being done. -! lsub = 1 - no longer used -! = 2 - beta* -! = 3 - cons* -! = 4 - ldef* -! = 5 - posw* -! = 6 - theta* -! = 7 - tmarx* -! = 8 - geom* -! magnet control flag for magnetostatic analysis. input data. -! ncycle cycle number. accumulated in osolty.f -! note first time through oasemb.f , ncycle = 0. -! newtnt control flag for permanent copy of newton. -! newton iteration type. input data. -! newton : = 1 full newton raphson -! 2 modified newton raphson -! 3 newton raphson with strain correct. -! 4 direct substitution -! 5 direct substitution followed by n.r. -! 6 direct substitution with line search -! 7 full newton raphson with secant initial stress -! 8 secant method -! 9 full newton raphson with line search -! noshr control flag for calculation interlaminar shears for -! elements 22,45, and 75. input data. -!ees -! -! jactch = 1 or 2 if elements are activated or deactivated -! = 3 if elements are adaptively remeshed or rezoned -! = 0 normally / reset to 0 when assembly is done -! ifricsh = 0 call to fricsh in otest not needed -! = 1 call to fricsh (nodal friction) in otest needed -! iremkin = 0 remove deactivated kinematic boundary conditions -! immediately - only in new input format (this is default) -! = 1 remove deactivated kinematic boundary conditions -! gradually - only in new input format -! iremfor = 0 remove force boundary conditions immediately - -! only in new input format (this is default) -! = 1 remove force boundary conditions gradually - -! only in new input format (this is default) -! ishearp set to 1 if shear panel elements are present in the model -! -! jspf = 0 not in spf loadcase -! > 0 in spf loadcase (jspf=1 during first increment) -! machining = 1 if the metal cutting feature is used, for memory allocation purpose -! = 0 (default) if no metal cutting feature required -! -! jlshell = 1 if there is a shell element in the mesh -! icompsol = 1 if there is a composite solid element in the mesh -! iupblgfo = 1 if follower force for point loads -! jcondir = 1 if contact priority option is used -! nstcrp = 0 (default) steady state creep flag (undocumented feature. -! if not 0, turns off special ncycle = 0 code in radial.f) -! nactive = number of active passes, if =1 then it's not a coupled analysis -! ipassref = reference ipass, if not in a multiphysics pass ipass=ipassref -! icheckmpc = value of mpc-check parameter option -! noline = set to 1 in osolty if no line seacrh should be done in ogetst -! icuring = set to 1 if the curing is included for the heat transfer analysis. -! ishrink = set to 1 if shrinkage strain is included for mechancial analysis. -! ioffsflg = 1 for small displacement beam/shell offsets -! = 2 for large displacement beam/shell offsets -! isetoff = 0 - do not apply beam/shell offsets -! = 1 - apply beam/shell offsets -! ioffsetm = min. value of offset flag -! iharmt = 1 global flag if a coupled analysis contains an harmonic pass -! inc_incdat = flag to record increment number of a new loadcase in incdat.f -! iautspc = flag for AutoSPC option -! ibrake = brake squeal in this increment -! icbush = set to 1 if cbush elements present in model -! istream_input = set to 1 for streaming input calling Marc as library -! iprsinp = set to 1 if pressure input, introduced so other variables -! such as h could be a function of pressure -! ivlsinp = set to 1 if velocity input, introduced so other variables -! such as h could be a function of velocity -! ipin_m = # of beam element with PIN flag -! jgnstr_glb = global control over pre or fast integrated composite shells -! imarc_return = Marc return flag for streaming input control -! iqvcimp = if non-zero, then the number of QVECT boundary conditions -! nqvceid = number of QVECT boundary conditions, where emisivity/absorbtion id entered -! istpnx = 1 if to stop at end of increment -! imicro1 = 1 if micro1 interface is used -! iaxisymm = set to 1 if axisymmetric analysis -! jbreakglue = set to 1 if breaking glued option is used -! iglstif = 1 if ddm and global stiffness matrix formed (sgi solver 6 or solver9) -! jfastasm = 1 do fast assembly using SuperForm code -! iwear = set to 1 if wear model, set to 2 if wear model and coordinates updated -! iwearcf = set to 1 to store nodal coefficient of friction for wear calculation -! imixmeth = set=1 then use nonlinear mixture material - allocate memory -! ielcmadyn = flag for magnetodynamics -! 0 - electromagnetics using newmark beta -! 1 - transient magnetics using backward euler -! idinout = flag to control if inside out elements should be deactivated -! igena_meth = 0 - generalized alpha parameters depend on whether or not contact -! is flagged (dynamic,7) -! 10 - generalized alpha parameters are optimized for a contact -! analysis (dynamic,8) -! 11 - generalized alpha parameters are optimized for an analysis -! without contact (dynamic,8) -! magf_meth = - Method to compute force in magnetostatic - structural -! = 1 - Virtual work method based on finite difference for the force computation -! = 2 - Maxwell stress tensor -! = 3 - Virtual work method based on local derivative for the force computation -! non_assumed = 1 no assumed strain formulation (forced) -! iredoboudry set to 1 if contact boundary needs to be recalculated -! ioffsz0 = 1 if composite are used with reference position.ne.0 -! icomplt = 1 global flag if a coupled analysis contains an complex pass -! mesh_dual = 1 two independent meshes are used in magnetodynamic/thermal/structural -! one for magnetodynamic and the other for the remaining passes -! iactrp = 1 in an analysis with global remeshing, include inactive -! rigid bodies on post file -! mgnewton = 1 Use full Newton Raphson iteration for magnetostatic pass -! -! iusedens > 0 if mass density is used in the analysis (dynamics, mass dependent loading) -! igsigd0 = 1 set varselem(igsigd) to zero in next oasemb -! iaem = 1 if marc is called from aem (0 - off - default) -! icosim = 1 if marc is used in co-simulation software (ADAMS-MARC) -! inodels = 1 nodal integration elements 239/240/241 present -! nlharm = 0 harmonic subincrements are linear -! = 1 harmonic subincrements are nonlinear -! iampini = 0 amplitude of previous harmonic subinc is initial estimate (default) -! = 1 zero amplitude is initial estimate -! iphasetr = 1 phase transformation material model is used -! iforminp flag indicating that contact is switched on via the CONTACT -! option in the input file (as opposed to the case that contact -! is switched on internally due to cyclic symmetry or model -! section creation) -! ispecerror = a+10*b (only for spectrum response analysis with missing mass option) -! a=0 or a=1 (modal shape with non-zero shift) -! b=0 or b=1 (recover with new assembly of stiffness matrix) -! icsprg = set to 1 if spring elements present in model -! -!*********************************************************************** -!$omp threadprivate(/marc_concom/) -!! diff --git a/src/marc/include/concom2019 b/src/marc/include/concom2019 deleted file mode 100644 index 292c250f2..000000000 --- a/src/marc/include/concom2019 +++ /dev/null @@ -1,434 +0,0 @@ -! common block definition file taken from respective MSC.Marc release and reformated to free format -!*********************************************************************** -! -! File: concom.cmn -! -! MSC.Marc include file -! -integer & - iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva, idyn, idynt,& - ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,& - ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,& - ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,& - itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,& - lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,& - icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,& - isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,& - ibukty, iassum, icnstd, icnstt, kmakmas, imethvp, iradrte, iradrtp, iupdate, iupdatp,& - ncycnt, marmen , idynme, ihavca, ispf, kmini, imixex, largtt, kdoela, iautofg,& - ipshftp, idntrc, ipore, jtablm, jtablc, isnecma, itrnspo, imsdif, jtrnspo, mcnear,& - imech, imecht, ielcmat, ielectt, magnett, imsdift, noplas, jtabls, jactch, jtablth,& - kgmsto , jpzo, ifricsh, iremkin, iremfor, ishearp, jspf, machining, jlshell, icompsol,& - iupblgfo, jcondir, nstcrp, nactive, ipassref, nstspnt, ibeart, icheckmpc, noline, icuring,& - ishrink, ioffsflg, isetoff, ioffsetm,iharmt, inc_incdat, iautspc, ibrake, icbush, istream_input,& - iprsinp, ivlsinp, ifirst_time,ipin_m, jgnstr_glb, imarc_return,iqvcinp, nqvceid, istpnx, imicro1,& - iaxisymm, jbreakglue,iglstif, jfastasm,iwear, iwearcf, imixmeth, ielcmadyn, idinout, igena_meth,& - magf_meth, non_assumed, iredoboudry, ioffsz0,icomplt, mesh_dual, iactrp, mgnewton, iusedens,igsigd0,& - iaem, icosim, inodels, nlharm, iampini, iphasetr, inonlcl, inonlct, iforminp,ispecerror,& - icsprg, imol, imolt, idatafit,iharmpar, inclcase -dimension :: ideva(60) -integer num_concom -parameter(num_concom=256) -common/marc_concom/& - iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva, idyn, idynt,& - ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,& - ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,& - ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,& - itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,& - lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,& - icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,& - isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,& - ibukty, iassum, icnstd, icnstt, kmakmas, imethvp, iradrte, iradrtp, iupdate, iupdatp,& - ncycnt, marmen, idynme, ihavca, ispf, kmini, imixex, largtt, kdoela, iautofg,& - ipshftp, idntrc, ipore, jtablm, jtablc, isnecma, itrnspo, imsdif, jtrnspo, mcnear,& - imech, imecht, ielcmat, ielectt, magnett, imsdift, noplas, jtabls, jactch, jtablth,& - kgmsto , jpzo, ifricsh, iremkin, iremfor, ishearp, jspf, machining, jlshell, icompsol,& - iupblgfo, jcondir, nstcrp, nactive, ipassref, nstspnt, ibeart, icheckmpc, noline, icuring,& - ishrink, ioffsflg, isetoff, ioffsetm,iharmt, inc_incdat, iautspc, ibrake, icbush, istream_input,& - iprsinp, ivlsinp, ifirst_time,ipin_m, jgnstr_glb, imarc_return,iqvcinp, nqvceid, istpnx, imicro1,& - iaxisymm, jbreakglue,iglstif, jfastasm,iwear, iwearcf, imixmeth, ielcmadyn, idinout, igena_meth,& - magf_meth, non_assumed, iredoboudry, ioffsz0,icomplt, mesh_dual, iactrp, mgnewton, iusedens,igsigd0,& - iaem, icosim, inodels, nlharm, iampini, iphasetr, inonlcl, inonlct, iforminp,ispecerror,& - icsprg, imol, imolt, idatafit,iharmpar, inclcase -! -! comments of variables: -! -! iacous Control flag for acoustic analysis. Input data. -! iacous=1 modal acoustic analysis. -! iacous=2 harmonic acoustic-structural analysis. -! iasmbl Control flag to indicate that operator matrix should be -! recalculated. -! iautth Control flag for AUTO THERM option. -! ibear Control flag for bearing analysis. Input data. -! icompl Control variable to indicate that a complex analysis is -! being performed. Either a Harmonic analysis with damping, -! or a harmonic electro-magnetic analysis. Input data. -! iconj Flag for EBE conjugate gradient solver (=solver 1, retired) -! Also used for VKI iterative solver. -! icreep Control flag for creep analysis. Input data. -! ideva(60) - debug print out flag -! 1 print element stiffness matrices, mass matrix -! 2 output matrices used in tying -! 3 force the solution of a nonpositive definite matrix -! 4 print info of connections to each node -! 5 info of gap convergence, internal heat generated, contact -! touching and separation -! 6 nodal value array during rezoning -! 7 tying info in CONRAD GAP option, fluid element numbers in -! CHANNEL option -! 8 output incremental displacements in local coord. system -! 9 latent heat output -! 10 stress-strain in local coord. system -! 11 additional info on interlaminar stress -! 12 output right hand side and solution vector -! 13 info of CPU resources used and memory available on NT -! 14 info of mesh adaption process, 2D outline information -! info of penetration checking for remeshing -! save .fem files after afmesh3d meshing -! 15 surface energy balance flag -! 16 print info regarding pyrolysis -! 17 print info of "streamline topology" -! 18 print mesh data changes after remeshing -! 19 print material flow stress data read in from *.mat file -! if unit flag is on, print out flow stress after conversion -! 20 print information on table input -! 21 print out information regarding kinematic boundary conditions -! 22 print out information regarding dist loads, point loads, film -! and foundations -! 23 print out information about automatic domain decomposition -! 24 print out iteration information in SuperForm status report file -! 25 print out information for ablation -! 26 print out information for films - Table input -! 27 print out the tying forces -! 28 print out for CASI solver, convection, -! 29 DDM single file debug printout -! 30 print out cavity debug info -! 31 print out welding related info -! 32 prints categorized DDM memory usage -! 33 print out the cutting info regarding machining feature -! 34 print out the list of quantities which can be defined via a table -! and for each quantity the supported independent variables -! 35 print out detailed coupling region info -! 36 print out solver debug info level 1 (Least Detailed) -! 37 print out solver debug info level 1 (Medium Detailed) -! 38 print out solver debug info level 1 (Very Detailed) -! 39 print detailed memory allocation info -! 40 print out marc-adams debug info -! 41 output rezone mapping post file for debugging -! 42 output post file after calling oprofos() for debugging -! 43 debug printout for vcct -! 44 debug printout for progressive failure -! 45 print out automatically generated midside node coordinates (arecrd) -! 46 print out message about routine and location, where the ibort is raised (ibort_inc) -! 47 print out summary message of element variables on a -! group-basis after all the automatic changes have been -! made (em_ellibp) -! 48 Automatically generate check results based on max and min vals. -! These vals are stored in the checkr file, which is inserted -! into the *dat file by the generate_check_results script from /marc/tools -! 49 Automatically generate check results based on the real calculated values -! at the sppecified check result locations. -! These vals are stored in the checkr file, which is inserted -! into the *dat file by the update_check_results script from /marc/tools -! 50 generate a file containing the resistance or capacity matrix; -! this file can be used to compare results with a reference file -! 51 print out detailed information for segment-to-segment contact -! 52 print out detailed relative displacement information -! for uniaxial sliding contact -! 53 print out detailed sliding direction information for -! uniaxial sliding contact -! 54 print out detailed information for edges attached to a curve -! 55 print information related to viscoelasticity calculations -! 56 print out detailed information for element coloring for multithreading -! 57 print out extra overheads due to multi-threading. -! These overhead includes (i) time and (ii) memory. -! The memory report will be summed over all the children. -! -! -! 58 debug output for ELSTO usage -! -! idyn Control flag for dynamics. Input data. -! 1 = eigenvalue extraction and / or modal superposition -! 2 = Newmark Beta and Single Step Houbolt (ssh with idynme=1) -! 3 = Houbolt -! 4 = Central difference -! 5 = Newer central difference -! idynt Copy of idyn at begining of increment -! ielas Control flag for ELASTIC analysis. Input data. -! Set by user or automatically turned on by Fourier option. -! Implies that each load case is treated separately. -! In Adaptive meshing analysis , forces re-analysis until -! convergence obtained. -! Also seriously misused to indicate no convergence. -! = 1 elastic option with fourier analysis -! = 2 elastic option without fourier analysis -! =-1 no convergence in recycles or max # increments reached -! Set to 1 if ELASTIC or SUBSTRUC parameter cards are used, -! or if fourier option is used. -! Then set to 2 if not fourier analysis. -! ielcma Control flag for electromagnetic analysis. Input data. -! ielcma = 1 Harmonic formulation -! ielcma = 2 Transient formulation -! ielect Control flag for electrostatic option. Input data. -! iform Control flag indicating that contact will be performed. -! ifour Control flag for Fourier analysis. -! 0 = Odd and even terms. -! 1 = symmetric (cosine) terms -! 2 = antisymmetric (sine) terms. -! iharm Control flag to indicate that a harmonic analysis will -! be performed. May change between passes. -! ihcps Control flag for coupled thermal - stress analysis. -! iheat Control flag for heat transfer analysis. Input data. -! iheatt Permanent control flag for heat transfer analysis. -! Note in coupled analysis iheatt will remain as one, -! but iheat will be zero in stress pass. -! ihresp Control flag to indicate to perform a harmonic subincrement. -! ijoule Control flag for Joule heating. -! ilem Control flag to determin which vector is to be transformed. -! Control flag to see where one is: -! ilem = 1 - elem.f -! ilem = 2 - initst.f -! ilem = 3 - pressr.f -! ilem = 3 - fstif.f -! ilem = 4 - jflux.f -! ilem = 4 - strass.f -! ilem = 5 - mass.f -! ilem = 5 - osolty.f -! ilnmom Control flag for soil - pore pressure calculation. Input data. -! ilnmom = 0 - perform only pore pressure calculation. -! = 1 - couples pore pressure - displacement analysis -! iloren Control flag for DeLorenzi J-Integral evaluation. Input data. -! inc Increment number. -! incext Control flag indicating that currently working on a -! subincrement. -! Could be due to harmonics , damping component (bearing), -! stiffness component (bearing), auto therm creep or -! old viscoplaticity -! incsub Sub-increment number. -! ipass Control flag for which part of coupled analysis. -! ipass = -1 - reset to base values -! ipass = 0 - do nothing -! ipass = 1 - stress part -! ipass = 2 - heat transfer part -! iplres Flag indicating that either second matrix is stored. -! dynamic analysis - mass matrix -! heat transfer - specific heat matrix -! buckle - initial stress stiffness -! ipois Control flag indicating Poisson type analysis -! ipois = 1 for heat transfer -! = 1 for heat transfer part of coupled -! = 1 for bearing -! = 1 for electrostatic -! = 1 for magnetostatic -! ipoist Permanent copy of ipois. In coupled analysis , ipois = 0 -! in stress portion, yet ipoist will still =1. -! irpflo global flag for rigid plastic flow analysis -! = 1 eularian formulation -! = 2 regular formulation; rigid material present in the analysis - -! ismall control flag to indicate small displacement analysis. input data. -! ismall = 0 - large disp included. -! ismall = 1 - small displacement. -! the flag is changing between passes. -! ismalt permanent copy of ismall . in heat transfer portion of -! coupled analysis ismall =0 , but ismalt remains the same. -! isoil control flag indicating that soil / pore pressure -! calculation . input data. -! ispect control flag for response spectrum calculation. input data. -! ispnow control flag to indicate to perform a spectrum response -! calculation now. -! istore store stresses flag. -! istore = 0 in elem.f and if first pass of creep -! convergence checking in ogetst.f -! or harmonic analysis or thruc.f if not -! converged. -! iswep control flag for eigenvalue analysis. -! iswep=1 - go do extraction process -! ithcrp control flag for auto therm creep option. input data. -! itherm control flag for either temperature dependent material -! properties and/or thermal loads. -! iupblg control flag for follower force option. input data. -! iupdat control flag for update lagrange option for current element. -! jacflg control flag for lanczos iteration method. input data. -! jel control flag indicating that total load applied in -! increment, ignore previous solution. -! jel = 1 in increment 0 -! = 1 if elastic or fourier -! = 1 in subincrements with elastic and adaptive -! jparks control flag for j integral by parks method. input data. -! largst control flag for finite strain plasticity. input data. -! lfond control variable that indicates if doing elastic -! foundation or film calculation. influences whether -! this is volumetric or surface integration. -! loadup control flag that indicates that nonlinearity occurred -! during previous increment. -! loaduq control flag that indicates that nonlinearity occurred. -! lodcor control flag for switching on the residual load correction. -! notice in input stage lodcor=0 means no loadcor, -! after omarc lodcor=1 means no loadcor -! lovl control flag for determining which "overlay" is to -! be called from ellib. -! lovl = 1 omarc -! = 2 oaread -! = 3 opress -! = 4 oasemb -! = 5 osolty -! = 6 ogetst -! = 7 oscinc -! = 8 odynam -! = 9 opmesh -! = 10 omesh2 -! = 11 osetz -! = 12 oass -! = 13 oincdt -! = 14 oasmas -! = 15 ofluas -! = 16 ofluso -! = 17 oshtra -! = 18 ocass -! = 19 osoltc -! = 20 orezon -! = 21 otest -! = 22 oeigen -! lsub control variable to determine which part of element -! assembly function is being done. -! lsub = 1 - no longer used -! = 2 - beta* -! = 3 - cons* -! = 4 - ldef* -! = 5 - posw* -! = 6 - theta* -! = 7 - tmarx* -! = 8 - geom* -! magnet control flag for magnetostatic analysis. input data. -! ncycle cycle number. accumulated in osolty.f -! note first time through oasemb.f , ncycle = 0. -! newtnt control flag for permanent copy of newton. -! newton iteration type. input data. -! newton : = 1 full newton raphson -! 2 modified newton raphson -! 3 newton raphson with strain correct. -! 4 direct substitution -! 5 direct substitution followed by n.r. -! 6 direct substitution with line search -! 7 full newton raphson with secant initial stress -! 8 secant method -! 9 full newton raphson with line search -! noshr control flag for calculation interlaminar shears for -! elements 22,45, and 75. input data. -!ees -! -! jactch = 1 or 2 if elements are activated or deactivated -! = 3 if elements are adaptively remeshed or rezoned -! = 0 normally / reset to 0 when assembly is done -! ifricsh = 0 call to fricsh in otest not needed -! = 1 call to fricsh (nodal friction) in otest needed -! iremkin = 0 remove deactivated kinematic boundary conditions -! immediately - only in new input format (this is default) -! = 1 remove deactivated kinematic boundary conditions -! gradually - only in new input format -! iremfor = 0 remove force boundary conditions immediately - -! only in new input format (this is default) -! = 1 remove force boundary conditions gradually - -! only in new input format (this is default) -! ishearp set to 1 if shear panel elements are present in the model -! -! jspf = 0 not in spf loadcase -! > 0 in spf loadcase (jspf=1 during first increment) -! machining = 1 if the metal cutting feature is used, for memory allocation purpose -! = 0 (default) if no metal cutting feature required -! -! jlshell = 1 if there is a shell element in the mesh -! icompsol = 1 if there is a composite solid element in the mesh -! iupblgfo = 1 if follower force for point loads -! jcondir = 1 if contact priority option is used -! nstcrp = 0 (default) steady state creep flag (undocumented feature. -! if not 0, turns off special ncycle = 0 code in radial.f) -! nactive = number of active passes, if =1 then it's not a coupled analysis -! ipassref = reference ipass, if not in a multiphysics pass ipass=ipassref -! icheckmpc = value of mpc-check parameter option -! noline = set to 1 in osolty if no line seacrh should be done in ogetst -! icuring = set to 1 if the curing is included for the heat transfer analysis. -! ishrink = set to 1 if shrinkage strain is included for mechancial analysis. -! ioffsflg = 1 for small displacement beam/shell offsets -! = 2 for large displacement beam/shell offsets -! isetoff = 0 - do not apply beam/shell offsets -! = 1 - apply beam/shell offsets -! ioffsetm = min. value of offset flag -! iharmt = 1 global flag if a coupled analysis contains an harmonic pass -! inc_incdat = flag to record increment number of a new loadcase in incdat.f -! iautspc = flag for AutoSPC option -! ibrake = brake squeal in this increment -! icbush = set to 1 if cbush elements present in model -! istream_input = set to 1 for streaming input calling Marc as library -! iprsinp = set to 1 if pressure input, introduced so other variables -! such as h could be a function of pressure -! ivlsinp = set to 1 if velocity input, introduced so other variables -! such as h could be a function of velocity -! ipin_m = # of beam element with PIN flag -! jgnstr_glb = global control over pre or fast integrated composite shells -! imarc_return = Marc return flag for streaming input control -! iqvcimp = if non-zero, then the number of QVECT boundary conditions -! nqvceid = number of QVECT boundary conditions, where emisivity/absorbtion id entered -! istpnx = 1 if to stop at end of increment -! imicro1 = 1 if micro1 interface is used -! iaxisymm = set to 1 if axisymmetric analysis -! jbreakglue = set to 1 if breaking glued option is used -! iglstif = 1 if ddm and global stiffness matrix formed (sgi solver 6 or solver9) -! jfastasm = 1 do fast assembly using SuperForm code -! iwear = set to 1 if wear model, set to 2 if wear model and coordinates updated -! iwearcf = set to 1 to store nodal coefficient of friction for wear calculation -! imixmeth = set=1 then use nonlinear mixture material - allocate memory -! ielcmadyn = flag for magnetodynamics -! 0 - electromagnetics using newmark beta -! 1 - transient magnetics using backward euler -! idinout = flag to control if inside out elements should be deactivated -! igena_meth = 0 - generalized alpha parameters depend on whether or not contact -! is flagged (dynamic,7) -! 10 - generalized alpha parameters are optimized for a contact -! analysis (dynamic,8) -! 11 - generalized alpha parameters are optimized for an analysis -! without contact (dynamic,8) -! magf_meth = - Method to compute force in magnetostatic - structural -! = 1 - Virtual work method based on finite difference for the force computation -! = 2 - Maxwell stress tensor -! = 3 - Virtual work method based on local derivative for the force computation -! non_assumed = 1 no assumed strain formulation (forced) -! iredoboudry set to 1 if contact boundary needs to be recalculated -! ioffsz0 = 1 if composite are used with reference position.ne.0 -! icomplt = 1 global flag if a coupled analysis contains an complex pass -! mesh_dual = 1 two independent meshes are used in magnetodynamic/thermal/structural -! one for magnetodynamic and the other for the remaining passes -! iactrp = 1 in an analysis with global remeshing, include inactive -! rigid bodies on post file -! mgnewton = 1 Use full Newton Raphson iteration for magnetostatic pass -! -! iusedens > 0 if mass density is used in the analysis (dynamics, mass dependent loading) -! igsigd0 = 1 set varselem(igsigd) to zero in next oasemb -! iaem = 1 if marc is called from aem (0 - off - default) -! icosim = 1 if marc is used in co-simulation software (ADAMS-MARC) -! inodels = 1 nodal integration elements 239/240/241 present -! nlharm = 0 harmonic subincrements are linear -! = 1 harmonic subincrements are nonlinear -! iampini = 0 amplitude of previous harmonic subinc is initial estimate (default) -! = 1 zero amplitude is initial estimate -! iphasetr = 1 phase transformation material model is used -! iforminp flag indicating that contact is switched on via the CONTACT -! option in the input file (as opposed to the case that contact -! is switched on internally due to cyclic symmetry or model -! section creation) -! ispecerror = a+10*b (only for spectrum response analysis with missing mass option) -! a=0 or a=1 (modal shape with non-zero shift) -! b=0 or b=1 (recover with new assembly of stiffness matrix) -! icsprg = set to 1 if spring elements present in model -! imol Control flag for molecualr diffusion pass -! imolt Permanent control flag for molecualr diffusion pass -! Note in coupled analysis imolt will remain as one, -! but imol will be zero in stress pass or thermal pass. -! idatafit = run Marc to fit parameters -! iharmpar = 1 if harmonic parameter option is used -! inclcase load case increment use for cyclic plasticity data fitting -! -!*********************************************************************** -!$omp threadprivate(/marc_concom/) -!! diff --git a/src/marc/include/concom2019.1 b/src/marc/include/concom2019.1 deleted file mode 100644 index 73e8eb992..000000000 --- a/src/marc/include/concom2019.1 +++ /dev/null @@ -1,439 +0,0 @@ -! common block definition file taken from respective MSC.Marc release and reformated to free format -!*********************************************************************** -! -! File: concom.cmn -! -! MSC.Marc include file -! -integer & - iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva, idyn, idynt,& - ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,& - ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,& - ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,& - itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,& - lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,& - icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,& - isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,& - ibukty, iassum, icnstd, icnstt, kmakmas, imethvp, iradrte, iradrtp, iupdate, iupdatp,& - ncycnt, marmen , idynme, ihavca, ispf, kmini, imixex, largtt, kdoela, iautofg,& - ipshftp, idntrc, ipore, jtablm, jtablc, isnecma, itrnspo, imsdif, jtrnspo, mcnear,& - imech, imecht, ielcmat, ielectt, magnett, imsdift, noplas, jtabls, jactch, jtablth,& - kgmsto , jpzo, ifricsh, iremkin, iremfor, ishearp, jspf, machining, jlshell, icompsol,& - iupblgfo, jcondir, nstcrp, nactive, ipassref, nstspnt, ibeart, icheckmpc, noline, icuring,& - ishrink, ioffsflg, isetoff, ioffsetm,iharmt, inc_incdat, iautspc, ibrake, icbush, istream_input,& - iprsinp, ivlsinp, ifirst_time,ipin_m, jgnstr_glb, imarc_return,iqvcinp, nqvceid, istpnx, imicro1,& - iaxisymm, jbreakglue,iglstif, jfastasm,iwear, iwearcf, imixmeth, ielcmadyn, idinout, igena_meth,& - magf_meth, non_assumed, iredoboudry, ioffsz0,icomplt, mesh_dual, iactrp, mgnewton, iusedens,igsigd0,& - iaem, icosim, inodels, nlharm, iampini, iphasetr, inonlcl, inonlct, iforminp,ispecerror,& - icsprg, imol, imolt, idatafit,iharmpar, inclcase, imultifreq,init_elas -dimension :: ideva(60) -integer num_concom -parameter(num_concom=258) -common/marc_concom/& - iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva, idyn, idynt,& - ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,& - ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,& - ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,& - itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,& - lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,& - icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,& - isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,& - ibukty, iassum, icnstd, icnstt, kmakmas, imethvp, iradrte, iradrtp, iupdate, iupdatp,& - ncycnt, marmen, idynme, ihavca, ispf, kmini, imixex, largtt, kdoela, iautofg,& - ipshftp, idntrc, ipore, jtablm, jtablc, isnecma, itrnspo, imsdif, jtrnspo, mcnear,& - imech, imecht, ielcmat, ielectt, magnett, imsdift, noplas, jtabls, jactch, jtablth,& - kgmsto , jpzo, ifricsh, iremkin, iremfor, ishearp, jspf, machining, jlshell, icompsol,& - iupblgfo, jcondir, nstcrp, nactive, ipassref, nstspnt, ibeart, icheckmpc, noline, icuring,& - ishrink, ioffsflg, isetoff, ioffsetm,iharmt, inc_incdat, iautspc, ibrake, icbush, istream_input,& - iprsinp, ivlsinp, ifirst_time,ipin_m, jgnstr_glb, imarc_return,iqvcinp, nqvceid, istpnx, imicro1,& - iaxisymm, jbreakglue,iglstif, jfastasm,iwear, iwearcf, imixmeth, ielcmadyn, idinout, igena_meth,& - magf_meth, non_assumed, iredoboudry, ioffsz0,icomplt, mesh_dual, iactrp, mgnewton, iusedens,igsigd0,& - iaem, icosim, inodels, nlharm, iampini, iphasetr, inonlcl, inonlct, iforminp,ispecerror,& - icsprg, imol, imolt, idatafit,iharmpar, inclcase, imultifreq,init_elas -! -! comments of variables: -! -! iacous Control flag for acoustic analysis. Input data. -! iacous=1 modal acoustic analysis. -! iacous=2 harmonic acoustic-structural analysis. -! iasmbl Control flag to indicate that operator matrix should be -! recalculated. -! iautth Control flag for AUTO THERM option. -! ibear Control flag for bearing analysis. Input data. -! icompl Control variable to indicate that a complex analysis is -! being performed. Either a Harmonic analysis with damping, -! or a harmonic electro-magnetic analysis. Input data. -! iconj Flag for EBE conjugate gradient solver (=solver 1, retired) -! Also used for VKI iterative solver. -! icreep Control flag for creep analysis. Input data. -! ideva(60) - debug print out flag -! 1 print element stiffness matrices, mass matrix -! 2 output matrices used in tying -! 3 force the solution of a nonpositive definite matrix -! 4 print info of connections to each node -! 5 info of gap convergence, internal heat generated, contact -! touching and separation -! 6 nodal value array during rezoning -! 7 tying info in CONRAD GAP option, fluid element numbers in -! CHANNEL option -! 8 output incremental displacements in local coord. system -! 9 latent heat output -! 10 stress-strain in local coord. system -! 11 additional info on interlaminar stress -! 12 output right hand side and solution vector -! 13 info of CPU resources used and memory available on NT -! 14 info of mesh adaption process, 2D outline information -! info of penetration checking for remeshing -! save .fem files after afmesh3d meshing -! 15 surface energy balance flag -! 16 print info regarding pyrolysis -! 17 print info of "streamline topology" -! 18 print mesh data changes after remeshing -! 19 print material flow stress data read in from *.mat file -! if unit flag is on, print out flow stress after conversion -! 20 print information on table input -! 21 print out information regarding kinematic boundary conditions -! 22 print out information regarding dist loads, point loads, film -! and foundations -! 23 print out information about automatic domain decomposition -! 24 print out iteration information in SuperForm status report file -! 25 print out information for ablation -! 26 print out information for films - Table input -! 27 print out the tying forces -! 28 print out for CASI solver, convection, -! 29 DDM single file debug printout -! 30 print out cavity debug info -! 31 print out welding related info -! 32 prints categorized DDM memory usage -! 33 print out the cutting info regarding machining feature -! 34 print out the list of quantities which can be defined via a table -! and for each quantity the supported independent variables -! 35 print out detailed coupling region info -! 36 print out solver debug info level 1 (Least Detailed) -! 37 print out solver debug info level 1 (Medium Detailed) -! 38 print out solver debug info level 1 (Very Detailed) -! 39 print detailed memory allocation info -! 40 print out marc-adams debug info -! 41 output rezone mapping post file for debugging -! 42 output post file after calling oprofos() for debugging -! 43 debug printout for vcct -! 44 debug printout for progressive failure -! 45 print out automatically generated midside node coordinates (arecrd) -! 46 print out message about routine and location, where the ibort is raised (ibort_inc) -! 47 print out summary message of element variables on a -! group-basis after all the automatic changes have been -! made (em_ellibp) -! 48 Automatically generate check results based on max and min vals. -! These vals are stored in the checkr file, which is inserted -! into the *dat file by the generate_check_results script from /marc/tools -! 49 Automatically generate check results based on the real calculated values -! at the sppecified check result locations. -! These vals are stored in the checkr file, which is inserted -! into the *dat file by the update_check_results script from /marc/tools -! 50 generate a file containing the resistance or capacity matrix; -! this file can be used to compare results with a reference file -! 51 print out detailed information for segment-to-segment contact -! 52 print out detailed relative displacement information -! for uniaxial sliding contact -! 53 print out detailed sliding direction information for -! uniaxial sliding contact -! 54 print out detailed information for edges attached to a curve -! 55 print information related to viscoelasticity calculations -! 56 print out detailed information for element coloring for multithreading -! 57 print out extra overheads due to multi-threading. -! These overhead includes (i) time and (ii) memory. -! The memory report will be summed over all the children. -! -! -! 58 debug output for ELSTO usage -! -! idyn Control flag for dynamics. Input data. -! 1 = eigenvalue extraction and / or modal superposition -! 2 = Newmark Beta and Single Step Houbolt (ssh with idynme=1) -! 3 = Houbolt -! 4 = Central difference -! 5 = Newer central difference -! idynt Copy of idyn at begining of increment -! ielas Control flag for ELASTIC analysis. Input data. -! Set by user or automatically turned on by Fourier option. -! Implies that each load case is treated separately. -! In Adaptive meshing analysis , forces re-analysis until -! convergence obtained. -! Also seriously misused to indicate no convergence. -! = 1 elastic option with fourier analysis -! = 2 elastic option without fourier analysis -! =-1 no convergence in recycles or max # increments reached -! Set to 1 if ELASTIC or SUBSTRUC parameter cards are used, -! or if fourier option is used. -! Then set to 2 if not fourier analysis. -! ielcma Control flag for electromagnetic analysis. Input data. -! ielcma = 1 Harmonic formulation -! ielcma = 2 Transient formulation -! ielect Control flag for electrostatic option. Input data. -! iform Control flag indicating that contact will be performed. -! ifour Control flag for Fourier analysis. -! 0 = Odd and even terms. -! 1 = symmetric (cosine) terms -! 2 = antisymmetric (sine) terms. -! iharm Control flag to indicate that a harmonic analysis will -! be performed. May change between passes. -! ihcps Control flag for coupled thermal - stress analysis. -! iheat Control flag for heat transfer analysis. Input data. -! iheatt Permanent control flag for heat transfer analysis. -! Note in coupled analysis iheatt will remain as one, -! but iheat will be zero in stress pass. -! ihresp Control flag to indicate to perform a harmonic subincrement. -! ijoule Control flag for Joule heating. -! ilem Control flag to determin which vector is to be transformed. -! Control flag to see where one is: -! ilem = 1 - elem.f -! ilem = 2 - initst.f -! ilem = 3 - pressr.f -! ilem = 3 - fstif.f -! ilem = 4 - jflux.f -! ilem = 4 - strass.f -! ilem = 5 - mass.f -! ilem = 5 - osolty.f -! ilnmom Control flag for soil - pore pressure calculation. Input data. -! ilnmom = 0 - perform only pore pressure calculation. -! = 1 - couples pore pressure - displacement analysis -! iloren Control flag for DeLorenzi J-Integral evaluation. Input data. -! inc Increment number. -! incext Control flag indicating that currently working on a -! subincrement. -! Could be due to harmonics , damping component (bearing), -! stiffness component (bearing), auto therm creep or -! old viscoplaticity -! incsub Sub-increment number. -! ipass Control flag for which part of coupled analysis. -! ipass = -1 - reset to base values -! ipass = 0 - do nothing -! ipass = 1 - stress part -! ipass = 2 - heat transfer part -! iplres Flag indicating that either second matrix is stored. -! dynamic analysis - mass matrix -! heat transfer - specific heat matrix -! buckle - initial stress stiffness -! ipois Control flag indicating Poisson type analysis -! ipois = 1 for heat transfer -! = 1 for heat transfer part of coupled -! = 1 for bearing -! = 1 for electrostatic -! = 1 for magnetostatic -! ipoist Permanent copy of ipois. In coupled analysis , ipois = 0 -! in stress portion, yet ipoist will still =1. -! irpflo global flag for rigid plastic flow analysis -! = 1 eularian formulation -! = 2 regular formulation; rigid material present in the analysis - -! ismall control flag to indicate small displacement analysis. input data. -! ismall = 0 - large disp included. -! ismall = 1 - small displacement. -! the flag is changing between passes. -! ismalt permanent copy of ismall . in heat transfer portion of -! coupled analysis ismall =0 , but ismalt remains the same. -! isoil control flag indicating that soil / pore pressure -! calculation . input data. -! ispect control flag for response spectrum calculation. input data. -! ispnow control flag to indicate to perform a spectrum response -! calculation now. -! istore store stresses flag. -! istore = 0 in elem.f and if first pass of creep -! convergence checking in ogetst.f -! or harmonic analysis or thruc.f if not -! converged. -! iswep control flag for eigenvalue analysis. -! iswep=1 - go do extraction process -! ithcrp control flag for auto therm creep option. input data. -! itherm control flag for either temperature dependent material -! properties and/or thermal loads. -! iupblg control flag for follower force option. input data. -! iupdat control flag for update lagrange option for current element. -! jacflg control flag for lanczos iteration method. input data. -! jel control flag indicating that total load applied in -! increment, ignore previous solution. -! jel = 1 in increment 0 -! = 1 if elastic or fourier -! = 1 in subincrements with elastic and adaptive -! jparks control flag for j integral by parks method. input data. -! largst control flag for finite strain plasticity. input data. -! lfond control variable that indicates if doing elastic -! foundation or film calculation. influences whether -! this is volumetric or surface integration. -! loadup control flag that indicates that nonlinearity occurred -! during previous increment. -! loaduq control flag that indicates that nonlinearity occurred. -! lodcor control flag for switching on the residual load correction. -! notice in input stage lodcor=0 means no loadcor, -! after omarc lodcor=1 means no loadcor -! lovl control flag for determining which "overlay" is to -! be called from ellib. -! lovl = 1 omarc -! = 2 oaread -! = 3 opress -! = 4 oasemb -! = 5 osolty -! = 6 ogetst -! = 7 oscinc -! = 8 odynam -! = 9 opmesh -! = 10 omesh2 -! = 11 osetz -! = 12 oass -! = 13 oincdt -! = 14 oasmas -! = 15 ofluas -! = 16 ofluso -! = 17 oshtra -! = 18 ocass -! = 19 osoltc -! = 20 orezon -! = 21 otest -! = 22 oeigen -! lsub control variable to determine which part of element -! assembly function is being done. -! lsub = 1 - no longer used -! = 2 - beta* -! = 3 - cons* -! = 4 - ldef* -! = 5 - posw* -! = 6 - theta* -! = 7 - tmarx* -! = 8 - geom* -! magnet control flag for magnetostatic analysis. input data. -! ncycle cycle number. accumulated in osolty.f -! note first time through oasemb.f , ncycle = 0. -! newtnt control flag for permanent copy of newton. -! newton iteration type. input data. -! newton : = 1 full newton raphson -! 2 modified newton raphson -! 3 newton raphson with strain correct. -! 4 direct substitution -! 5 direct substitution followed by n.r. -! 6 direct substitution with line search -! 7 full newton raphson with secant initial stress -! 8 secant method -! 9 full newton raphson with line search -! noshr control flag for calculation interlaminar shears for -! elements 22,45, and 75. input data. -!ees -! -! jactch = 1 or 2 if elements are activated or deactivated -! = 3 if elements are adaptively remeshed or rezoned -! = 0 normally / reset to 0 when assembly is done -! ifricsh = 0 call to fricsh in otest not needed -! = 1 call to fricsh (nodal friction) in otest needed -! iremkin = 0 remove deactivated kinematic boundary conditions -! immediately - only in new input format (this is default) -! = 1 remove deactivated kinematic boundary conditions -! gradually - only in new input format -! iremfor = 0 remove force boundary conditions immediately - -! only in new input format (this is default) -! = 1 remove force boundary conditions gradually - -! only in new input format (this is default) -! ishearp set to 1 if shear panel elements are present in the model -! -! jspf = 0 not in spf loadcase -! > 0 in spf loadcase (jspf=1 during first increment) -! machining = 1 if the metal cutting feature is used, for memory allocation purpose -! = 0 (default) if no metal cutting feature required -! -! jlshell = 1 if there is a shell element in the mesh -! icompsol = 1 if there is a composite solid element in the mesh -! iupblgfo = 1 if follower force for point loads -! jcondir = 1 if contact priority option is used -! nstcrp = 0 (default) steady state creep flag (undocumented feature. -! if not 0, turns off special ncycle = 0 code in radial.f) -! nactive = number of active passes, if =1 then it's not a coupled analysis -! ipassref = reference ipass, if not in a multiphysics pass ipass=ipassref -! icheckmpc = value of mpc-check parameter option -! noline = set to 1 in osolty if no line seacrh should be done in ogetst -! icuring = set to 1 if the curing is included for the heat transfer analysis. -! ishrink = set to 1 if shrinkage strain is included for mechancial analysis. -! ioffsflg = 1 for small displacement beam/shell offsets -! = 2 for large displacement beam/shell offsets -! isetoff = 0 - do not apply beam/shell offsets -! = 1 - apply beam/shell offsets -! ioffsetm = min. value of offset flag -! iharmt = 1 global flag if a coupled analysis contains an harmonic pass -! inc_incdat = flag to record increment number of a new loadcase in incdat.f -! iautspc = flag for AutoSPC option -! ibrake = brake squeal in this increment -! icbush = set to 1 if cbush elements present in model -! istream_input = set to 1 for streaming input calling Marc as library -! iprsinp = set to 1 if pressure input, introduced so other variables -! such as h could be a function of pressure -! ivlsinp = set to 1 if velocity input, introduced so other variables -! such as h could be a function of velocity -! ipin_m = # of beam element with PIN flag -! jgnstr_glb = global control over pre or fast integrated composite shells -! imarc_return = Marc return flag for streaming input control -! iqvcimp = if non-zero, then the number of QVECT boundary conditions -! nqvceid = number of QVECT boundary conditions, where emisivity/absorbtion id entered -! istpnx = 1 if to stop at end of increment -! imicro1 = 1 if micro1 interface is used -! iaxisymm = set to 1 if axisymmetric analysis -! jbreakglue = set to 1 if breaking glued option is used -! iglstif = 1 if ddm and global stiffness matrix formed (sgi solver 6 or solver9) -! jfastasm = 1 do fast assembly using SuperForm code -! iwear = set to 1 if wear model, set to 2 if wear model and coordinates updated -! iwearcf = set to 1 to store nodal coefficient of friction for wear calculation -! imixmeth = set=1 then use nonlinear mixture material - allocate memory -! ielcmadyn = flag for magnetodynamics -! 0 - electromagnetics using newmark beta -! 1 - transient magnetics using backward euler -! idinout = flag to control if inside out elements should be deactivated -! igena_meth = 0 - generalized alpha parameters depend on whether or not contact -! is flagged (dynamic,7) -! 10 - generalized alpha parameters are optimized for a contact -! analysis (dynamic,8) -! 11 - generalized alpha parameters are optimized for an analysis -! without contact (dynamic,8) -! magf_meth = - Method to compute force in magnetostatic - structural -! = 1 - Virtual work method based on finite difference for the force computation -! = 2 - Maxwell stress tensor -! = 3 - Virtual work method based on local derivative for the force computation -! non_assumed = 1 no assumed strain formulation (forced) -! iredoboudry set to 1 if contact boundary needs to be recalculated -! ioffsz0 = 1 if composite are used with reference position.ne.0 -! icomplt = 1 global flag if a coupled analysis contains an complex pass -! mesh_dual = 1 two independent meshes are used in magnetodynamic/thermal/structural -! one for magnetodynamic and the other for the remaining passes -! iactrp = 1 in an analysis with global remeshing, include inactive -! rigid bodies on post file -! mgnewton = 1 Use full Newton Raphson iteration for magnetostatic pass -! -! iusedens > 0 if mass density is used in the analysis (dynamics, mass dependent loading) -! igsigd0 = 1 set varselem(igsigd) to zero in next oasemb -! iaem = 1 if marc is called from aem (0 - off - default) -! icosim = 1 if marc is used in co-simulation software (ADAMS-MARC) -! inodels = 1 nodal integration elements 239/240/241 present -! nlharm = 0 harmonic subincrements are linear -! = 1 harmonic subincrements are nonlinear -! iampini = 0 amplitude of previous harmonic subinc is initial estimate (default) -! = 1 zero amplitude is initial estimate -! iphasetr = 1 phase transformation material model is used -! iforminp flag indicating that contact is switched on via the CONTACT -! option in the input file (as opposed to the case that contact -! is switched on internally due to cyclic symmetry or model -! section creation) -! ispecerror = a+10*b (only for spectrum response analysis with missing mass option) -! a=0 or a=1 (modal shape with non-zero shift) -! b=0 or b=1 (recover with new assembly of stiffness matrix) -! icsprg = set to 1 if spring elements present in model -! imol Control flag for molecualr diffusion pass -! imolt Permanent control flag for molecualr diffusion pass -! Note in coupled analysis imolt will remain as one, -! but imol will be zero in stress pass or thermal pass. -! idatafit = run Marc to fit parameters -! iharmpar = 1 if harmonic parameter option is used -! inclcase load case increment use for cyclic plasticity data fitting -! imultifreq flag to indicate how many harmonic magnetodynamic passes are computed in coupled -! magnetodynamic/thermal(/structural) analyses. -! 0 or 1 one pass 2 two passes 3 or more is not supported -! init_elas use elastic stress-strain law as the material tangent for -! the first cycle of an increment -! -!*********************************************************************** -!$omp threadprivate(/marc_concom/) -!! diff --git a/src/marc/include/creeps2018 b/src/marc/include/creeps2018 deleted file mode 100644 index 09550f501..000000000 --- a/src/marc/include/creeps2018 +++ /dev/null @@ -1,66 +0,0 @@ -! common block definition file taken from respective MSC.Marc release and reformated to free format -!*********************************************************************** -! -! File: creeps.cmn -! -! MSC.Marc include file -! -real(pReal) cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b -integer icfte,icfst,icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,& - icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa -real(pReal) time_beg_lcase,time_beg_inc,fractol,time_beg_pst -real(pReal) fraction_donn,timinc_ol2 -! -integer num_creepsr,num_creepsi,num_creeps2r -parameter(num_creepsr=7) -parameter(num_creepsi=17) -parameter(num_creeps2r=6) -common/marc_creeps/cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b,icfte,icfst,& - icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa -common/marc_creeps2/time_beg_lcase,time_beg_inc,fractol,time_beg_pst,fraction_donn,timinc_ol2 -! -! cptim Total time at begining of increment. -! timinc Incremental time for this step. -! icfte Local copy number of slopes of creep strain rate function -! versus temperature. Is -1 if exponent law used. -! icfst Local copy number of slopes of creep strain rate function -! versus equivalent stress. Is -1 if exponent law used. -! icfeq Local copy number of slopes of creep strain rate function -! versus equivalent strain. Is -1 if exponent law used. -! icftm Local copy number of slopes of creep strain rate function -! versus time. Is -1 if exponent law used. -! icetem Element number that needs to be checked for creep convergence -! or, if negative, the number of elements that need to -! be checked. In the latter case the elements to check -! are stored in ielcp. -! mcreep Maximum nuber of iterations for explicit creep. -! jcreep Counter of number of iterations for explicit creep -! procedure. jcreep must be .le. mcreep -! icpa Pointer to constant in creep strain rate expression. -! icftmp Pointer to temperature dependent creep strain rate data. -! icfstr Pointer to equivalent stress dependent creep strain rate data. -! icfqcp Pointer to equivalent creep strain dependent creep strain -! rate data. -! icfcpm Pointer to equivalent creep strain rate dependent -! creep strain rate data. -! icrppr Permanent copy of icreep -! icrcha Control flag for creep convergence checking , if set to -! 1 then testing on absolute change in stress and creep -! strain, not relative testing. Input data. -! icpb Pointer to storage of material id cross reference numbers. -! iicpmt -! iicpa Pointer to constant in creep strain rate expression -! -! time_beg_lcase time at the beginning of the current load case -! time_beg_inc time at the beginning of the current increment -! fractol fraction of loadcase or increment time when we -! consider it to be finished -! time_beg_pst time corresponding to first increment to be -! read in from thermal post file for auto step -! -! timinc_old Time step of the previous increment -! -!*********************************************************************** -!!$omp threadprivate(/marc_creeps/) -!!$omp threadprivate(/marc_creeps2/) -!! diff --git a/src/marc/include/creeps2018.1 b/src/marc/include/creeps2018.1 deleted file mode 100644 index 09550f501..000000000 --- a/src/marc/include/creeps2018.1 +++ /dev/null @@ -1,66 +0,0 @@ -! common block definition file taken from respective MSC.Marc release and reformated to free format -!*********************************************************************** -! -! File: creeps.cmn -! -! MSC.Marc include file -! -real(pReal) cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b -integer icfte,icfst,icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,& - icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa -real(pReal) time_beg_lcase,time_beg_inc,fractol,time_beg_pst -real(pReal) fraction_donn,timinc_ol2 -! -integer num_creepsr,num_creepsi,num_creeps2r -parameter(num_creepsr=7) -parameter(num_creepsi=17) -parameter(num_creeps2r=6) -common/marc_creeps/cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b,icfte,icfst,& - icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa -common/marc_creeps2/time_beg_lcase,time_beg_inc,fractol,time_beg_pst,fraction_donn,timinc_ol2 -! -! cptim Total time at begining of increment. -! timinc Incremental time for this step. -! icfte Local copy number of slopes of creep strain rate function -! versus temperature. Is -1 if exponent law used. -! icfst Local copy number of slopes of creep strain rate function -! versus equivalent stress. Is -1 if exponent law used. -! icfeq Local copy number of slopes of creep strain rate function -! versus equivalent strain. Is -1 if exponent law used. -! icftm Local copy number of slopes of creep strain rate function -! versus time. Is -1 if exponent law used. -! icetem Element number that needs to be checked for creep convergence -! or, if negative, the number of elements that need to -! be checked. In the latter case the elements to check -! are stored in ielcp. -! mcreep Maximum nuber of iterations for explicit creep. -! jcreep Counter of number of iterations for explicit creep -! procedure. jcreep must be .le. mcreep -! icpa Pointer to constant in creep strain rate expression. -! icftmp Pointer to temperature dependent creep strain rate data. -! icfstr Pointer to equivalent stress dependent creep strain rate data. -! icfqcp Pointer to equivalent creep strain dependent creep strain -! rate data. -! icfcpm Pointer to equivalent creep strain rate dependent -! creep strain rate data. -! icrppr Permanent copy of icreep -! icrcha Control flag for creep convergence checking , if set to -! 1 then testing on absolute change in stress and creep -! strain, not relative testing. Input data. -! icpb Pointer to storage of material id cross reference numbers. -! iicpmt -! iicpa Pointer to constant in creep strain rate expression -! -! time_beg_lcase time at the beginning of the current load case -! time_beg_inc time at the beginning of the current increment -! fractol fraction of loadcase or increment time when we -! consider it to be finished -! time_beg_pst time corresponding to first increment to be -! read in from thermal post file for auto step -! -! timinc_old Time step of the previous increment -! -!*********************************************************************** -!!$omp threadprivate(/marc_creeps/) -!!$omp threadprivate(/marc_creeps2/) -!! diff --git a/src/marc/include/creeps2019 b/src/marc/include/creeps2019 deleted file mode 100644 index 09550f501..000000000 --- a/src/marc/include/creeps2019 +++ /dev/null @@ -1,66 +0,0 @@ -! common block definition file taken from respective MSC.Marc release and reformated to free format -!*********************************************************************** -! -! File: creeps.cmn -! -! MSC.Marc include file -! -real(pReal) cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b -integer icfte,icfst,icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,& - icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa -real(pReal) time_beg_lcase,time_beg_inc,fractol,time_beg_pst -real(pReal) fraction_donn,timinc_ol2 -! -integer num_creepsr,num_creepsi,num_creeps2r -parameter(num_creepsr=7) -parameter(num_creepsi=17) -parameter(num_creeps2r=6) -common/marc_creeps/cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b,icfte,icfst,& - icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa -common/marc_creeps2/time_beg_lcase,time_beg_inc,fractol,time_beg_pst,fraction_donn,timinc_ol2 -! -! cptim Total time at begining of increment. -! timinc Incremental time for this step. -! icfte Local copy number of slopes of creep strain rate function -! versus temperature. Is -1 if exponent law used. -! icfst Local copy number of slopes of creep strain rate function -! versus equivalent stress. Is -1 if exponent law used. -! icfeq Local copy number of slopes of creep strain rate function -! versus equivalent strain. Is -1 if exponent law used. -! icftm Local copy number of slopes of creep strain rate function -! versus time. Is -1 if exponent law used. -! icetem Element number that needs to be checked for creep convergence -! or, if negative, the number of elements that need to -! be checked. In the latter case the elements to check -! are stored in ielcp. -! mcreep Maximum nuber of iterations for explicit creep. -! jcreep Counter of number of iterations for explicit creep -! procedure. jcreep must be .le. mcreep -! icpa Pointer to constant in creep strain rate expression. -! icftmp Pointer to temperature dependent creep strain rate data. -! icfstr Pointer to equivalent stress dependent creep strain rate data. -! icfqcp Pointer to equivalent creep strain dependent creep strain -! rate data. -! icfcpm Pointer to equivalent creep strain rate dependent -! creep strain rate data. -! icrppr Permanent copy of icreep -! icrcha Control flag for creep convergence checking , if set to -! 1 then testing on absolute change in stress and creep -! strain, not relative testing. Input data. -! icpb Pointer to storage of material id cross reference numbers. -! iicpmt -! iicpa Pointer to constant in creep strain rate expression -! -! time_beg_lcase time at the beginning of the current load case -! time_beg_inc time at the beginning of the current increment -! fractol fraction of loadcase or increment time when we -! consider it to be finished -! time_beg_pst time corresponding to first increment to be -! read in from thermal post file for auto step -! -! timinc_old Time step of the previous increment -! -!*********************************************************************** -!!$omp threadprivate(/marc_creeps/) -!!$omp threadprivate(/marc_creeps2/) -!! diff --git a/src/marc/include/creeps2019.1 b/src/marc/include/creeps2019.1 deleted file mode 100644 index 09550f501..000000000 --- a/src/marc/include/creeps2019.1 +++ /dev/null @@ -1,66 +0,0 @@ -! common block definition file taken from respective MSC.Marc release and reformated to free format -!*********************************************************************** -! -! File: creeps.cmn -! -! MSC.Marc include file -! -real(pReal) cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b -integer icfte,icfst,icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,& - icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa -real(pReal) time_beg_lcase,time_beg_inc,fractol,time_beg_pst -real(pReal) fraction_donn,timinc_ol2 -! -integer num_creepsr,num_creepsi,num_creeps2r -parameter(num_creepsr=7) -parameter(num_creepsi=17) -parameter(num_creeps2r=6) -common/marc_creeps/cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b,icfte,icfst,& - icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa -common/marc_creeps2/time_beg_lcase,time_beg_inc,fractol,time_beg_pst,fraction_donn,timinc_ol2 -! -! cptim Total time at begining of increment. -! timinc Incremental time for this step. -! icfte Local copy number of slopes of creep strain rate function -! versus temperature. Is -1 if exponent law used. -! icfst Local copy number of slopes of creep strain rate function -! versus equivalent stress. Is -1 if exponent law used. -! icfeq Local copy number of slopes of creep strain rate function -! versus equivalent strain. Is -1 if exponent law used. -! icftm Local copy number of slopes of creep strain rate function -! versus time. Is -1 if exponent law used. -! icetem Element number that needs to be checked for creep convergence -! or, if negative, the number of elements that need to -! be checked. In the latter case the elements to check -! are stored in ielcp. -! mcreep Maximum nuber of iterations for explicit creep. -! jcreep Counter of number of iterations for explicit creep -! procedure. jcreep must be .le. mcreep -! icpa Pointer to constant in creep strain rate expression. -! icftmp Pointer to temperature dependent creep strain rate data. -! icfstr Pointer to equivalent stress dependent creep strain rate data. -! icfqcp Pointer to equivalent creep strain dependent creep strain -! rate data. -! icfcpm Pointer to equivalent creep strain rate dependent -! creep strain rate data. -! icrppr Permanent copy of icreep -! icrcha Control flag for creep convergence checking , if set to -! 1 then testing on absolute change in stress and creep -! strain, not relative testing. Input data. -! icpb Pointer to storage of material id cross reference numbers. -! iicpmt -! iicpa Pointer to constant in creep strain rate expression -! -! time_beg_lcase time at the beginning of the current load case -! time_beg_inc time at the beginning of the current increment -! fractol fraction of loadcase or increment time when we -! consider it to be finished -! time_beg_pst time corresponding to first increment to be -! read in from thermal post file for auto step -! -! timinc_old Time step of the previous increment -! -!*********************************************************************** -!!$omp threadprivate(/marc_creeps/) -!!$omp threadprivate(/marc_creeps2/) -!! From cffc9aa3c8f5a651fc841dea8255f44aeafb141e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 12:06:10 +0100 Subject: [PATCH 017/219] shorter, more systematic names --- PRIVATE | 2 +- .../Kinematics_Thermal_Expansion.config | 0 .../Phase_Damage.config | 0 .../Phase_DisloUCLA_Tungsten.config | 0 .../Phase_Dislotwin_TWIP-Steel-FeMnC.yaml | 0 .../Phase_Dislotwin_Tungsten.yaml | 0 .../Phase_Isotropic_AluminumIsotropic.yaml | 0 .../Phase_Isotropic_FreeSurface.yaml | 0 ...se_None_IsotropicVolumePreservation.config | 0 .../Phase_None_Orthorhombic.config | 0 .../Phase_Nonlocal_Aluminum.config | 0 .../Phase_Nonlocal_Nickel.config | 0 .../Phase_Phenopowerlaw_Aluminum.yaml | 0 .../Phase_Phenopowerlaw_BCC-Ferrite.yaml | 0 .../Phase_Phenopowerlaw_BCC-Martensite.yaml | 0 .../Phase_Phenopowerlaw_Gold.yaml | 0 .../Phase_Phenopowerlaw_Magnesium.yaml | 0 .../Phase_Phenopowerlaw_cpTi.yaml | 0 .../Phase_Thermal.config | 0 .../Source_Damage_IsoBrittle.config | 0 .../Source_Thermal_Dissipation.config | 0 examples/{configuration => config}/debug.yaml | 0 .../Homogenization_Isostrain_Parallel3.config | 0 .../Homogenization_None_Dummy.config | 0 .../mechanical/RGC_8grains.yaml | 9 +++++++++ .../mechanical/isostrain_Taylor.yaml | 2 ++ .../{configuration => config}/numerics.yaml | 0 .../Homogenization_Damage_NonLocal.config | 3 --- .../Homogenization_Isostrain_SX.config | 3 --- .../Homogenization_Isostrain_Taylor2.config | 3 --- .../Homogenization_RGC_8Grains.config | 19 ------------------- .../Homogenization_Thermal_Conduction.config | 3 --- 32 files changed, 12 insertions(+), 32 deletions(-) rename examples/{configuration => config}/Kinematics_Thermal_Expansion.config (100%) rename examples/{configuration => config}/Phase_Damage.config (100%) rename examples/{configuration => config}/Phase_DisloUCLA_Tungsten.config (100%) rename examples/{configuration => config}/Phase_Dislotwin_TWIP-Steel-FeMnC.yaml (100%) rename examples/{configuration => config}/Phase_Dislotwin_Tungsten.yaml (100%) rename examples/{configuration => config}/Phase_Isotropic_AluminumIsotropic.yaml (100%) rename examples/{configuration => config}/Phase_Isotropic_FreeSurface.yaml (100%) rename examples/{configuration => config}/Phase_None_IsotropicVolumePreservation.config (100%) rename examples/{configuration => config}/Phase_None_Orthorhombic.config (100%) rename examples/{configuration => config}/Phase_Nonlocal_Aluminum.config (100%) rename examples/{configuration => config}/Phase_Nonlocal_Nickel.config (100%) rename examples/{configuration => config}/Phase_Phenopowerlaw_Aluminum.yaml (100%) rename examples/{configuration => config}/Phase_Phenopowerlaw_BCC-Ferrite.yaml (100%) rename examples/{configuration => config}/Phase_Phenopowerlaw_BCC-Martensite.yaml (100%) rename examples/{configuration => config}/Phase_Phenopowerlaw_Gold.yaml (100%) rename examples/{configuration => config}/Phase_Phenopowerlaw_Magnesium.yaml (100%) rename examples/{configuration => config}/Phase_Phenopowerlaw_cpTi.yaml (100%) rename examples/{configuration => config}/Phase_Thermal.config (100%) rename examples/{configuration => config}/Source_Damage_IsoBrittle.config (100%) rename examples/{configuration => config}/Source_Thermal_Dissipation.config (100%) rename examples/{configuration => config}/debug.yaml (100%) rename examples/{configuration => config/homogenization}/Homogenization_Isostrain_Parallel3.config (100%) rename examples/{configuration => config/homogenization}/Homogenization_None_Dummy.config (100%) create mode 100644 examples/config/homogenization/mechanical/RGC_8grains.yaml create mode 100644 examples/config/homogenization/mechanical/isostrain_Taylor.yaml rename examples/{configuration => config}/numerics.yaml (100%) delete mode 100644 examples/configuration/Homogenization_Damage_NonLocal.config delete mode 100644 examples/configuration/Homogenization_Isostrain_SX.config delete mode 100644 examples/configuration/Homogenization_Isostrain_Taylor2.config delete mode 100644 examples/configuration/Homogenization_RGC_8Grains.config delete mode 100644 examples/configuration/Homogenization_Thermal_Conduction.config diff --git a/PRIVATE b/PRIVATE index 0d572a227..888d95604 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 0d572a2277a65097be81c31db671d4d193685831 +Subproject commit 888d956040237bb9677e46863ac38604160b0234 diff --git a/examples/configuration/Kinematics_Thermal_Expansion.config b/examples/config/Kinematics_Thermal_Expansion.config similarity index 100% rename from examples/configuration/Kinematics_Thermal_Expansion.config rename to examples/config/Kinematics_Thermal_Expansion.config diff --git a/examples/configuration/Phase_Damage.config b/examples/config/Phase_Damage.config similarity index 100% rename from examples/configuration/Phase_Damage.config rename to examples/config/Phase_Damage.config diff --git a/examples/configuration/Phase_DisloUCLA_Tungsten.config b/examples/config/Phase_DisloUCLA_Tungsten.config similarity index 100% rename from examples/configuration/Phase_DisloUCLA_Tungsten.config rename to examples/config/Phase_DisloUCLA_Tungsten.config diff --git a/examples/configuration/Phase_Dislotwin_TWIP-Steel-FeMnC.yaml b/examples/config/Phase_Dislotwin_TWIP-Steel-FeMnC.yaml similarity index 100% rename from examples/configuration/Phase_Dislotwin_TWIP-Steel-FeMnC.yaml rename to examples/config/Phase_Dislotwin_TWIP-Steel-FeMnC.yaml diff --git a/examples/configuration/Phase_Dislotwin_Tungsten.yaml b/examples/config/Phase_Dislotwin_Tungsten.yaml similarity index 100% rename from examples/configuration/Phase_Dislotwin_Tungsten.yaml rename to examples/config/Phase_Dislotwin_Tungsten.yaml diff --git a/examples/configuration/Phase_Isotropic_AluminumIsotropic.yaml b/examples/config/Phase_Isotropic_AluminumIsotropic.yaml similarity index 100% rename from examples/configuration/Phase_Isotropic_AluminumIsotropic.yaml rename to examples/config/Phase_Isotropic_AluminumIsotropic.yaml diff --git a/examples/configuration/Phase_Isotropic_FreeSurface.yaml b/examples/config/Phase_Isotropic_FreeSurface.yaml similarity index 100% rename from examples/configuration/Phase_Isotropic_FreeSurface.yaml rename to examples/config/Phase_Isotropic_FreeSurface.yaml diff --git a/examples/configuration/Phase_None_IsotropicVolumePreservation.config b/examples/config/Phase_None_IsotropicVolumePreservation.config similarity index 100% rename from examples/configuration/Phase_None_IsotropicVolumePreservation.config rename to examples/config/Phase_None_IsotropicVolumePreservation.config diff --git a/examples/configuration/Phase_None_Orthorhombic.config b/examples/config/Phase_None_Orthorhombic.config similarity index 100% rename from examples/configuration/Phase_None_Orthorhombic.config rename to examples/config/Phase_None_Orthorhombic.config diff --git a/examples/configuration/Phase_Nonlocal_Aluminum.config b/examples/config/Phase_Nonlocal_Aluminum.config similarity index 100% rename from examples/configuration/Phase_Nonlocal_Aluminum.config rename to examples/config/Phase_Nonlocal_Aluminum.config diff --git a/examples/configuration/Phase_Nonlocal_Nickel.config b/examples/config/Phase_Nonlocal_Nickel.config similarity index 100% rename from examples/configuration/Phase_Nonlocal_Nickel.config rename to examples/config/Phase_Nonlocal_Nickel.config diff --git a/examples/configuration/Phase_Phenopowerlaw_Aluminum.yaml b/examples/config/Phase_Phenopowerlaw_Aluminum.yaml similarity index 100% rename from examples/configuration/Phase_Phenopowerlaw_Aluminum.yaml rename to examples/config/Phase_Phenopowerlaw_Aluminum.yaml diff --git a/examples/configuration/Phase_Phenopowerlaw_BCC-Ferrite.yaml b/examples/config/Phase_Phenopowerlaw_BCC-Ferrite.yaml similarity index 100% rename from examples/configuration/Phase_Phenopowerlaw_BCC-Ferrite.yaml rename to examples/config/Phase_Phenopowerlaw_BCC-Ferrite.yaml diff --git a/examples/configuration/Phase_Phenopowerlaw_BCC-Martensite.yaml b/examples/config/Phase_Phenopowerlaw_BCC-Martensite.yaml similarity index 100% rename from examples/configuration/Phase_Phenopowerlaw_BCC-Martensite.yaml rename to examples/config/Phase_Phenopowerlaw_BCC-Martensite.yaml diff --git a/examples/configuration/Phase_Phenopowerlaw_Gold.yaml b/examples/config/Phase_Phenopowerlaw_Gold.yaml similarity index 100% rename from examples/configuration/Phase_Phenopowerlaw_Gold.yaml rename to examples/config/Phase_Phenopowerlaw_Gold.yaml diff --git a/examples/configuration/Phase_Phenopowerlaw_Magnesium.yaml b/examples/config/Phase_Phenopowerlaw_Magnesium.yaml similarity index 100% rename from examples/configuration/Phase_Phenopowerlaw_Magnesium.yaml rename to examples/config/Phase_Phenopowerlaw_Magnesium.yaml diff --git a/examples/configuration/Phase_Phenopowerlaw_cpTi.yaml b/examples/config/Phase_Phenopowerlaw_cpTi.yaml similarity index 100% rename from examples/configuration/Phase_Phenopowerlaw_cpTi.yaml rename to examples/config/Phase_Phenopowerlaw_cpTi.yaml diff --git a/examples/configuration/Phase_Thermal.config b/examples/config/Phase_Thermal.config similarity index 100% rename from examples/configuration/Phase_Thermal.config rename to examples/config/Phase_Thermal.config diff --git a/examples/configuration/Source_Damage_IsoBrittle.config b/examples/config/Source_Damage_IsoBrittle.config similarity index 100% rename from examples/configuration/Source_Damage_IsoBrittle.config rename to examples/config/Source_Damage_IsoBrittle.config diff --git a/examples/configuration/Source_Thermal_Dissipation.config b/examples/config/Source_Thermal_Dissipation.config similarity index 100% rename from examples/configuration/Source_Thermal_Dissipation.config rename to examples/config/Source_Thermal_Dissipation.config diff --git a/examples/configuration/debug.yaml b/examples/config/debug.yaml similarity index 100% rename from examples/configuration/debug.yaml rename to examples/config/debug.yaml diff --git a/examples/configuration/Homogenization_Isostrain_Parallel3.config b/examples/config/homogenization/Homogenization_Isostrain_Parallel3.config similarity index 100% rename from examples/configuration/Homogenization_Isostrain_Parallel3.config rename to examples/config/homogenization/Homogenization_Isostrain_Parallel3.config diff --git a/examples/configuration/Homogenization_None_Dummy.config b/examples/config/homogenization/Homogenization_None_Dummy.config similarity index 100% rename from examples/configuration/Homogenization_None_Dummy.config rename to examples/config/homogenization/Homogenization_None_Dummy.config diff --git a/examples/config/homogenization/mechanical/RGC_8grains.yaml b/examples/config/homogenization/mechanical/RGC_8grains.yaml new file mode 100644 index 000000000..0549e5ab2 --- /dev/null +++ b/examples/config/homogenization/mechanical/RGC_8grains.yaml @@ -0,0 +1,9 @@ +8Grains: + mechanical: + type: RGC + D_alpha: [4.0e-06, 4.0e-06, 2.0e-06] + a_g: [0.0, 0.0, 0.0] + c_alpha: 2.0 + cluster_size: [2, 2, 2] + output: [M, Delta_V, avg_a_dot, max_a_dot] + xi_alpha: 10.0 diff --git a/examples/config/homogenization/mechanical/isostrain_Taylor.yaml b/examples/config/homogenization/mechanical/isostrain_Taylor.yaml new file mode 100644 index 000000000..8f37a89c4 --- /dev/null +++ b/examples/config/homogenization/mechanical/isostrain_Taylor.yaml @@ -0,0 +1,2 @@ +Taylor: + mechanical: {type: isostrain} diff --git a/examples/configuration/numerics.yaml b/examples/config/numerics.yaml similarity index 100% rename from examples/configuration/numerics.yaml rename to examples/config/numerics.yaml diff --git a/examples/configuration/Homogenization_Damage_NonLocal.config b/examples/configuration/Homogenization_Damage_NonLocal.config deleted file mode 100644 index 13eb0135e..000000000 --- a/examples/configuration/Homogenization_Damage_NonLocal.config +++ /dev/null @@ -1,3 +0,0 @@ -damage nonlocal -initialDamage 1.0 -(output) damage diff --git a/examples/configuration/Homogenization_Isostrain_SX.config b/examples/configuration/Homogenization_Isostrain_SX.config deleted file mode 100644 index 40b26b554..000000000 --- a/examples/configuration/Homogenization_Isostrain_SX.config +++ /dev/null @@ -1,3 +0,0 @@ -[SX] -mech isostrain -nconstituents 1 diff --git a/examples/configuration/Homogenization_Isostrain_Taylor2.config b/examples/configuration/Homogenization_Isostrain_Taylor2.config deleted file mode 100644 index 5e1e899e7..000000000 --- a/examples/configuration/Homogenization_Isostrain_Taylor2.config +++ /dev/null @@ -1,3 +0,0 @@ -[Taylor2] -mech isostrain -nconstituents 2 \ No newline at end of file diff --git a/examples/configuration/Homogenization_RGC_8Grains.config b/examples/configuration/Homogenization_RGC_8Grains.config deleted file mode 100644 index c75c83ce0..000000000 --- a/examples/configuration/Homogenization_RGC_8Grains.config +++ /dev/null @@ -1,19 +0,0 @@ -[8Grains] -mech RGC -nconstituents 8 -clustersize 2 2 2 # product of these numbers must be equal to nconstituents(!) -clusterorientation 0.0 0.0 0.0 # orientation of cluster in terms of zxz Euler-angles in degree (random if not present) -# clusterorientation 0.0 26.57 0.0 # [012] -# clusterorientation 0.0 45.00 0.0 # [011] -# clusterorientation 0.0 26.57 24.10 # [112] -# clusterorientation 0.0 45.00 19.47 # [122] -# clusterorientation 0.0 45.00 35.26 # [111] -grainsize 4.0e-6 4.0e-6 2.0e-6 # in [m] -overproportionality 2.0e+0 # typical range between 0.001 to 1000 -scalingparameter 1.0e+1 # typical range between 0.001 to 1000 -(output) constitutivework -(output) magnitudemismatch -(output) penaltyenergy -(output) volumediscrepancy -(output) averagerelaxrate -(output) maximumrelaxrate \ No newline at end of file diff --git a/examples/configuration/Homogenization_Thermal_Conduction.config b/examples/configuration/Homogenization_Thermal_Conduction.config deleted file mode 100644 index 36fc7ea6e..000000000 --- a/examples/configuration/Homogenization_Thermal_Conduction.config +++ /dev/null @@ -1,3 +0,0 @@ -thermal conduction -t0 270.0 -(output) temperature From 6a2c1077235f18d530716b5ad1473c1026f7e1cd Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 12:34:16 +0100 Subject: [PATCH 018/219] consistent names for debugging --- examples/config/debug.yaml | 15 +++++---------- src/DAMASK_Marc.f90 | 2 +- src/grid/spectral_utilities.f90 | 12 ++++++------ src/mesh/FEM_utilities.f90 | 6 +++--- 4 files changed, 15 insertions(+), 20 deletions(-) diff --git a/examples/config/debug.yaml b/examples/config/debug.yaml index 49e863695..a28c04320 100644 --- a/examples/config/debug.yaml +++ b/examples/config/debug.yaml @@ -1,20 +1,15 @@ -### debugging parameters ### -## case sensitive keys -# example: -# -------- -# mesh: [basic, extensive] # switches on the "basic" and "extensive" debugging in mesh-related functions/subroutines -# - -mesh: [basic,extensive] # mesh.f90, possible value: basic, extensive material: [basic, extensive] # material.f90, possible values: basic, extensive constitutive: [basic, extensive, selective] # constitutive_*.f90 possible values: basic, extensive, selective crystallite: [basic, extensive, selective] # crystallite.f90 possible values: basic, extensive, selective homogenization: [basic, extensive, selective] # homogenization_*.f90 possible values: basic, extensive, selective cpfem: [basic, extensive, selective] # CPFEM.f90 possible values: basic, extensive, selective -grid: [basic, fft, restart, divergence, rotation, petsc] # DAMASK_spectral.f90 possible values: basic, fft, restart, divergence, rotation, petsc -marc: [basic] # MSC.MARC FEM solver possible values: basic # # Parameters for selective element: 1 # selected element for debugging integrationpoint: 1 # selected integration point for debugging grain: 1 # selected grain at ip for debugging + +# solver-specific +mesh: [basic] +grid: [basic, rotation, PETSc] +Marc: [basic] diff --git a/src/DAMASK_Marc.f90 b/src/DAMASK_Marc.f90 index c295de1ee..68265dbdb 100644 --- a/src/DAMASK_Marc.f90 +++ b/src/DAMASK_Marc.f90 @@ -256,7 +256,7 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, & if (.not. CPFEM_init_done) then CPFEM_init_done = .true. call CPFEM_initAll - debug_Marc => config_debug%get('marc',defaultVal=emptyList) + debug_Marc => config_debug%get('Marc',defaultVal=emptyList) debug_basic = debug_Marc%contains('basic') endif diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 97801cfb3..f512d9b6c 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -190,25 +190,25 @@ subroutine spectral_utilities_init !-------------------------------------------------------------------------------------------------- ! set debugging parameters + num_grid => config_numerics%get('grid',defaultVal=emptyDict) + debug_grid => config_debug%get('grid',defaultVal=emptyList) debugGeneral = debug_grid%contains('basic') debugRotation = debug_grid%contains('rotation') - debugPETSc = debug_grid%contains('petsc') - + debugPETSc = debug_grid%contains('PETSc') if(debugPETSc) print'(3(/,a),/)', & ' Initializing PETSc with debug options: ', & trim(PETScDebug), & - ' add more using the PETSc_Options keyword in numerics.yaml '; flush(IO_STDOUT) - - num_grid => config_numerics%get('grid',defaultVal=emptyDict) + ' add more using the "PETSc_options" keyword in numerics.yaml' + flush(IO_STDOUT) call PetscOptionsClear(PETSC_NULL_OPTIONS,ierr) CHKERRQ(ierr) if(debugPETSc) call PetscOptionsInsertString(PETSC_NULL_OPTIONS,trim(PETSCDEBUG),ierr) CHKERRQ(ierr) call PetscOptionsInsertString(PETSC_NULL_OPTIONS,& - num_grid%get_asString('petsc_options',defaultVal=''),ierr) + num_grid%get_asString('PETSc_options',defaultVal=''),ierr) CHKERRQ(ierr) grid1Red = grid(1)/2 + 1 diff --git a/src/mesh/FEM_utilities.f90 b/src/mesh/FEM_utilities.f90 index 4b3be8a42..a84e3559f 100644 --- a/src/mesh/FEM_utilities.f90 +++ b/src/mesh/FEM_utilities.f90 @@ -116,12 +116,12 @@ subroutine FEM_utilities_init structOrder = num_mesh%get_asInt('structOrder', defaultVal = 2) debug_mesh => config_debug%get('mesh',defaultVal=emptyList) - debugPETSc = debug_mesh%contains('petsc') + debugPETSc = debug_mesh%contains('PETSc') if(debugPETSc) print'(3(/,a),/)', & ' Initializing PETSc with debug options: ', & trim(PETScDebug), & - ' add more using the PETSc_Options keyword in numerics.yaml ' + ' add more using the "PETSc_options" keyword in numerics.yaml' flush(IO_STDOUT) call PetscOptionsClear(PETSC_NULL_OPTIONS,ierr) CHKERRQ(ierr) @@ -134,7 +134,7 @@ subroutine FEM_utilities_init &-mechanical_pc_type ml -mechanical_mg_levels_ksp_type chebyshev & &-mechanical_mg_levels_pc_type sor -mechanical_pc_ml_nullspace user',ierr) CHKERRQ(ierr) - call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_mesh%get_asString('petsc_options',defaultVal=''),ierr) + call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_mesh%get_asString('PETSc_options',defaultVal=''),ierr) CHKERRQ(ierr) write(petsc_optionsOrder,'(a,i0)') '-mechFE_petscspace_degree ', structOrder call PetscOptionsInsertString(PETSC_NULL_OPTIONS,trim(petsc_optionsOrder),ierr) From cb0d407ce4ca6ed95489a8cd0fff218af012525e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 12:40:01 +0100 Subject: [PATCH 019/219] not used --- examples/config/debug.yaml | 12 +++++------- src/CMakeLists.txt | 2 +- src/phase.f90 | 6 ------ 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/examples/config/debug.yaml b/examples/config/debug.yaml index a28c04320..94de168f4 100644 --- a/examples/config/debug.yaml +++ b/examples/config/debug.yaml @@ -1,13 +1,11 @@ material: [basic, extensive] # material.f90, possible values: basic, extensive constitutive: [basic, extensive, selective] # constitutive_*.f90 possible values: basic, extensive, selective -crystallite: [basic, extensive, selective] # crystallite.f90 possible values: basic, extensive, selective -homogenization: [basic, extensive, selective] # homogenization_*.f90 possible values: basic, extensive, selective cpfem: [basic, extensive, selective] # CPFEM.f90 possible values: basic, extensive, selective -# -# Parameters for selective -element: 1 # selected element for debugging -integrationpoint: 1 # selected integration point for debugging -grain: 1 # selected grain at ip for debugging + +# options for selective debugging +element: 1 +integrationpoint: 1 +grain: 1 # solver-specific mesh: [basic] diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0cb697013..c20754a67 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,7 +8,7 @@ file(GLOB damask-sources *.f90 *.c) # probably we should have a subfolder for MSC.Marc list(FILTER damask-sources EXCLUDE REGEX ".*CPFEM.f90") -list(FILTER damask-sources EXCLUDE REGEX ".*DAMASK_marc.*.f90") +list(FILTER damask-sources EXCLUDE REGEX ".*DAMASK_Marc.*.f90") list(FILTER damask-sources EXCLUDE REGEX ".*commercialFEM_fileList.*.f90") diff --git a/src/phase.f90 b/src/phase.f90 index add26ae0b..5a9eaa518 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -58,8 +58,6 @@ module phase grain end type tDebugOptions - type(tDebugOptions) :: debugCrystallite - integer, dimension(:), allocatable, public :: & !< ToDo: should be protected (bug in Intel compiler) phase_elasticityInstance, & phase_NstiffnessDegradations @@ -497,15 +495,11 @@ subroutine crystallite_init() class(tNode), pointer :: & num_crystallite, & - debug_crystallite, & ! pointer to debug options for crystallite phases print'(/,a)', ' <<<+- crystallite init -+>>>' - debug_crystallite => config_debug%get('crystallite', defaultVal=emptyList) - debugCrystallite%extensive = debug_crystallite%contains('extensive') - cMax = homogenization_maxNconstituents iMax = discretization_nIPs eMax = discretization_Nelems From d74c1534ed6b8308da2dd9b2021d76d3eba53314 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 12:43:27 +0100 Subject: [PATCH 020/219] bug fixes --- processing/legacy/gmsh_identifySurfaces.py | 16 +++++++++------- src/DAMASK_Marc.f90 | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/processing/legacy/gmsh_identifySurfaces.py b/processing/legacy/gmsh_identifySurfaces.py index 642b0a71e..9dbb81fbf 100755 --- a/processing/legacy/gmsh_identifySurfaces.py +++ b/processing/legacy/gmsh_identifySurfaces.py @@ -1,8 +1,9 @@ -#!/usr/bin/env python2.7 -# -*- coding: UTF-8 no BOM -*- +#!/usr/bin/env python3 -import os,re +import os +import re from optparse import OptionParser + import damask scriptName = os.path.splitext(os.path.basename(__file__))[0] @@ -11,6 +12,7 @@ scriptID = ' '.join([scriptName,damask.version]) def all_same(items,a): return all(x == a for x in items) + def func(seq): for x in seq: try: @@ -18,14 +20,14 @@ def func(seq): except ValueError: yield x + #-------------------------------------------------------------------------------------------------- # MAIN #-------------------------------------------------------------------------------------------------- +parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [file[s]]', + description =' Recognize bounding surfaces and append them as physical sufaces in the geo file.', + version = scriptID) -parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [file[s]]', description = """ -Recognize bounding surfaces and append them as physical sufaces in the geo file. - -""", version = scriptID) parser.add_option('-n','--numvol', dest = 'N', type='int', metavar='int', help='number of physical volumes' ) diff --git a/src/DAMASK_Marc.f90 b/src/DAMASK_Marc.f90 index 68265dbdb..e417be2fa 100644 --- a/src/DAMASK_Marc.f90 +++ b/src/DAMASK_Marc.f90 @@ -366,7 +366,7 @@ subroutine uedinc(inc,incsub) integer :: n, nqncomp, nqdatatype integer, save :: inc_written real(pReal), allocatable, dimension(:,:) :: d_n -#include QUOTE(PASTE(./marc/include/creeps,Marc4DAMASK)) ! creeps is needed for timinc (time increment) +#include QUOTE(PASTE(./Marc/include/creeps,Marc4DAMASK)) ! creeps is needed for timinc (time increment) if (inc > inc_written) then From 078baa14c7c6f606695bf1cc65c42e95f14c5451 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 13:00:41 +0100 Subject: [PATCH 021/219] addDisplacement is deprecated --- .gitlab-ci.yml | 15 --------------- .../homogenization/mechanical/RGC_8grains.yaml | 1 + ...ostrain_Taylor.yaml => isostrain_Taylor2.yaml} | 3 ++- .../config/phase/mechanical/elastic/Aluminum.yaml | 4 ++++ 4 files changed, 7 insertions(+), 16 deletions(-) rename examples/config/homogenization/mechanical/{isostrain_Taylor.yaml => isostrain_Taylor2.yaml} (52%) create mode 100644 examples/config/phase/mechanical/elastic/Aluminum.yaml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e16218946..9498a6b43 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -113,21 +113,6 @@ Pre_General: - release - release -Post_GeometryReconstruction: - stage: deprecated - script: spectral_geometryReconstruction/test.py - except: - - master - - release - -Post_OrientationAverageMisorientation: - stage: deprecated - script: - - OrientationAverageMisorientation/test.py - except: - - master - - release - ################################################################################################### compile_grid_Intel: stage: compile diff --git a/examples/config/homogenization/mechanical/RGC_8grains.yaml b/examples/config/homogenization/mechanical/RGC_8grains.yaml index 0549e5ab2..9200c364d 100644 --- a/examples/config/homogenization/mechanical/RGC_8grains.yaml +++ b/examples/config/homogenization/mechanical/RGC_8grains.yaml @@ -1,4 +1,5 @@ 8Grains: + N_constituents: 8 mechanical: type: RGC D_alpha: [4.0e-06, 4.0e-06, 2.0e-06] diff --git a/examples/config/homogenization/mechanical/isostrain_Taylor.yaml b/examples/config/homogenization/mechanical/isostrain_Taylor2.yaml similarity index 52% rename from examples/config/homogenization/mechanical/isostrain_Taylor.yaml rename to examples/config/homogenization/mechanical/isostrain_Taylor2.yaml index 8f37a89c4..3dc20fd87 100644 --- a/examples/config/homogenization/mechanical/isostrain_Taylor.yaml +++ b/examples/config/homogenization/mechanical/isostrain_Taylor2.yaml @@ -1,2 +1,3 @@ -Taylor: +Taylor2: + N_constituents: 2 mechanical: {type: isostrain} diff --git a/examples/config/phase/mechanical/elastic/Aluminum.yaml b/examples/config/phase/mechanical/elastic/Aluminum.yaml new file mode 100644 index 000000000..a1fa22a97 --- /dev/null +++ b/examples/config/phase/mechanical/elastic/Aluminum.yaml @@ -0,0 +1,4 @@ +Aluminum: + lattice: cF + mechanical: + elastic: {C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9, type: hooke} From 4614de4cb504bbe022049a3cba4cdc6eb9e32e26 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 13:07:05 +0100 Subject: [PATCH 022/219] phase out shell scripts --- .gitlab-ci.yml | 4 ++-- Makefile | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9498a6b43..2a618837f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -89,7 +89,7 @@ checkout: - git checkout $CI_COMMIT_SHA - git submodule update --init - source env/DAMASK.sh - - make processing + - ./installation/symlink_Processing.py except: - master - release @@ -224,7 +224,7 @@ SpectralRuntime: script: - module load $IntelCompiler $MPI_Intel $PETSc_Intel - cd $DAMASKROOT - - make clean grid processing OPTIMIZATION=AGGRESSIVE + - make clean grid OPTIMIZATION=AGGRESSIVE - cd $LOCAL_HOME/performance # location of old results - git checkout . # undo any changes (i.e. run time data from non-development branch) - cd $DAMASKROOT/PRIVATE/testing diff --git a/Makefile b/Makefile index 102b954bd..4bc110169 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ SHELL = /bin/sh # Makefile for the installation of DAMASK ######################################################################################## .PHONY: all -all: grid mesh processing +all: grid mesh .PHONY: grid grid: @@ -20,7 +20,3 @@ mesh: .PHONY: clean clean: @rm -rf build - -.PHONY: processing -processing: - @./installation/symlink_Processing.py ${MAKEFLAGS} From 44f89b94560cce2e8e22cd0b9fe2a84fd975c866 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 13:10:10 +0100 Subject: [PATCH 023/219] not used at the moment and in general, we should release more frequently --- installation/patch/README.md | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 installation/patch/README.md diff --git a/installation/patch/README.md b/installation/patch/README.md deleted file mode 100644 index 95f377691..000000000 --- a/installation/patch/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# DAMASK patching - -This folder contains patches that modify the functionality of the current development version of DAMASK ahead of the corresponding adoption in the official release. - -## Usage - -```bash -cd DAMASK_ROOT -patch -p1 < installation/patch/nameOfPatch -``` - -## Create patch -commit your changes - -```bash -git format-patch PATH_TO_COMPARE --stdout > -``` From b6a8754082f34c4cbdd447431846832596936fea Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 13:24:11 +0100 Subject: [PATCH 024/219] simplified --- .gitlab-ci.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2a618837f..0abc75047 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,8 +4,7 @@ stages: - python - deprecated - compile - - grid - - marc + - fortran - performance - createPackage - createDocumentation @@ -190,7 +189,7 @@ setup_mesh: ################################################################################################### pytest_fortran: - stage: grid + stage: fortran script: - module load $IntelCompiler $MPI_Intel $PETSc_Intel - cd pytest @@ -200,16 +199,14 @@ pytest_fortran: - release Phenopowerlaw_singleSlip: - stage: grid + stage: fortran script: Phenopowerlaw_singleSlip/test.py except: - master - release - -################################################################################################### J2_plasticBehavior: - stage: marc + stage: fortran script: - module load $IntelMarc $HDF5Marc $MSC - J2_plasticBehavior/test.py From 949c37c4d0d1f6f7da6882a62f8fd542fd3d0592 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 13:51:09 +0100 Subject: [PATCH 025/219] bugfix incorrect handling of NonSchmid behavior --- src/phase_mechanical_plastic_nonlocal.f90 | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/phase_mechanical_plastic_nonlocal.f90 b/src/phase_mechanical_plastic_nonlocal.f90 index 654cf08a3..d884f5117 100644 --- a/src/phase_mechanical_plastic_nonlocal.f90 +++ b/src/phase_mechanical_plastic_nonlocal.f90 @@ -253,11 +253,11 @@ module function plastic_nonlocal_init() result(myPlasticity) if(trim(phase%get_asString('lattice')) == 'cI') then a = pl%get_asFloats('a_nonSchmid',defaultVal = emptyRealArray) if(size(a) > 0) prm%nonSchmidActive = .true. - prm%nonSchmid_pos = lattice_nonSchmidMatrix(ini%N_sl,a,+1) - prm%nonSchmid_neg = lattice_nonSchmidMatrix(ini%N_sl,a,-1) + prm%nonSchmid_pos = lattice_nonSchmidMatrix(ini%N_sl,a,+1) + prm%nonSchmid_neg = lattice_nonSchmidMatrix(ini%N_sl,a,-1) else - prm%nonSchmid_pos = prm%Schmid - prm%nonSchmid_neg = prm%Schmid + prm%nonSchmid_pos = prm%Schmid + prm%nonSchmid_neg = prm%Schmid endif prm%h_sl_sl = lattice_interaction_SlipBySlip(ini%N_sl, & @@ -827,14 +827,14 @@ module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, & !screws if (prm%nonSchmidActive) then - v(:,3:4) = spread(v(:,1),2,2) - dv_dtau(:,3:4) = spread(dv_dtau(:,1),2,2) - dv_dtauNS(:,3:4) = spread(dv_dtauNS(:,1),2,2) - else do t = 3,4 call kinetics(v(:,t), dv_dtau(:,t), dv_dtauNS(:,t), & tau, tauNS(:,t), dst%tau_pass(:,me),2,Temperature, ph) enddo + else + v(:,3:4) = spread(v(:,1),2,2) + dv_dtau(:,3:4) = spread(dv_dtau(:,1),2,2) + dv_dtauNS(:,3:4) = spread(dv_dtauNS(:,1),2,2) endif stt%v(:,me) = pack(v,.true.) @@ -854,8 +854,8 @@ module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, & + prm%Schmid(i,j,s) * prm%Schmid(k,l,s) & * sum(rhoSgl(s,1:4) * dv_dtau(s,1:4)) * prm%b_sl(s) & + prm%Schmid(i,j,s) & - * ( prm%nonSchmid_pos(k,l,s) * rhoSgl(s,3) * dv_dtauNS(s,3) & - - prm%nonSchmid_neg(k,l,s) * rhoSgl(s,4) * dv_dtauNS(s,4)) * prm%b_sl(s) + * (+ prm%nonSchmid_pos(k,l,s) * rhoSgl(s,3) * dv_dtauNS(s,3) & + - prm%nonSchmid_neg(k,l,s) * rhoSgl(s,4) * dv_dtauNS(s,4)) * prm%b_sl(s) enddo end associate From 99865ac39c010b340e0ee9d69f7a5aa5578c6a22 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 17:04:50 +0100 Subject: [PATCH 026/219] DAMASK_NUM_THREADS does not exist anymore number of processes not needed --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 4bc110169..d38966bc5 100644 --- a/Makefile +++ b/Makefile @@ -8,13 +8,13 @@ all: grid mesh .PHONY: grid grid: @cmake -B build/grid -DDAMASK_SOLVER=GRID -DCMAKE_INSTALL_PREFIX=${PWD} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILDCMD_POST=${BUILDCMD_POST} -DBUILDCMD_PRE=${BUILDCMD_PRE} -DOPTIMIZATION=${OPTIMIZATION} -DOPENMP=${OPENMP} - @cmake --build build/grid --parallel ${DAMASK_NUM_THRADS} + @cmake --build build/grid --parallel @cmake --install build/grid .PHONY: mesh mesh: @cmake -B build/mesh -DDAMASK_SOLVER=MESH -DCMAKE_INSTALL_PREFIX=${PWD} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILDCMD_POST=${BUILDCMD_POST} -DBUILDCMD_PRE=${BUILDCMD_PRE} -DOPTIMIZATION=${OPTIMIZATION} -DOPENMP=${OPENMP} - @cmake --build build/mesh --parallel ${DAMASK_NUM_THRADS} + @cmake --build build/mesh --parallel @cmake --install build/mesh .PHONY: clean From 96d66a63b5b97a0390bbc3bdda0b2b1798ba736f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 17:15:56 +0100 Subject: [PATCH 027/219] streamlined --- .gitlab-ci.yml | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0abc75047..91f03c6af 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,17 +1,15 @@ --- stages: - - prepareAll + - prepare - python - - deprecated - compile - fortran - performance - - createPackage - - createDocumentation - - saveDocumentation - - updateMaster + - deploy + - backup + - update_master + - distclean - clean - - releaseLock ################################################################################################### before_script: @@ -73,7 +71,7 @@ variables: ################################################################################################### checkout: - stage: prepareAll + stage: prepare before_script: - echo $CI_PIPELINE_ID >> $LOCAL_HOME/GitLabCI.queue - while [ $(awk "/$CI_PIPELINE_ID/{print NR}" $LOCAL_HOME/GitLabCI.queue) != 1 ]; @@ -94,7 +92,7 @@ checkout: - release ################################################################################################### -pytest_python: +processing: stage: python script: - cd $DAMASKROOT/python @@ -104,8 +102,8 @@ pytest_python: - release ################################################################################################### -Pre_General: - stage: deprecated +preprocessing_deprecated: + stage: python script: PreProcessing/test.py except: - master @@ -153,7 +151,7 @@ compile_mesh_GNU: - master - release -compile_MARC: +compile_Marc: stage: compile script: - module load $IntelMarc $HDF5Marc $MSC @@ -188,7 +186,7 @@ setup_mesh: - release ################################################################################################### -pytest_fortran: +core: stage: fortran script: - module load $IntelCompiler $MPI_Intel $PETSc_Intel @@ -231,8 +229,8 @@ SpectralRuntime: - release ################################################################################################### -createTar: - stage: createPackage +source_distribution: + stage: deploy script: - cd $(mktemp -d) - $DAMASKROOT/PRIVATE/releasing/deployMe.sh $CI_COMMIT_SHA @@ -240,9 +238,8 @@ createTar: - master - release -################################################################################################### -Python: - stage: createDocumentation +library_documentation: + stage: deploy script: - echo 'tbd one matesting1' except: @@ -250,8 +247,8 @@ Python: - release ################################################################################################## -backupData: - stage: saveDocumentation +backup_runtime_measurement: + stage: backup script: - cd $LOCAL_HOME/performance # location of new runtime results - git commit -am"${CI_PIPELINE_ID}_${CI_COMMIT_SHA}" @@ -262,8 +259,8 @@ backupData: - development ################################################################################################## -mergeIntoMaster: - stage: updateMaster +merge_into_master: + stage: update_master script: - cd $DAMASKROOT - export TESTEDREV=$(git describe) # might be detached from development branch @@ -281,8 +278,8 @@ mergeIntoMaster: - development ################################################################################################### -removeData: - stage: clean +remove_data: + stage: distclean before_script: - echo "Removing data and lock of pipeline $CI_PIPELINE_ID" script: @@ -293,8 +290,8 @@ removeData: - release ################################################################################################### -removeLock: - stage: releaseLock +remove_lock: + stage: clean before_script: - echo "Removing lock of pipeline $CI_PIPELINE_ID" when: always From 3b6c97edb00624b4a1b6b86733be5ae580e04177 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 17:37:38 +0100 Subject: [PATCH 028/219] adjusting names --- examples/config/debug.yaml | 11 +++++------ examples/config/numerics.yaml | 2 -- src/CPFEM.f90 | 2 +- src/phase.f90 | 16 ++++++++-------- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/examples/config/debug.yaml b/examples/config/debug.yaml index 94de168f4..900873b25 100644 --- a/examples/config/debug.yaml +++ b/examples/config/debug.yaml @@ -1,13 +1,12 @@ -material: [basic, extensive] # material.f90, possible values: basic, extensive -constitutive: [basic, extensive, selective] # constitutive_*.f90 possible values: basic, extensive, selective -cpfem: [basic, extensive, selective] # CPFEM.f90 possible values: basic, extensive, selective +phase: [basic, extensive, selective] +CPFEM: [basic, extensive, selective] # options for selective debugging -element: 1 +element: 1 integrationpoint: 1 -grain: 1 +constituent: 1 # solver-specific -mesh: [basic] +mesh: [PETSc] grid: [basic, rotation, PETSc] Marc: [basic] diff --git a/examples/config/numerics.yaml b/examples/config/numerics.yaml index e25c86f5a..68a74e13c 100644 --- a/examples/config/numerics.yaml +++ b/examples/config/numerics.yaml @@ -42,12 +42,10 @@ grid: fftw_plan_mode: FFTW_PATIENT # reads the planing-rigor flag, see manual on www.fftw.org, Default FFTW_PATIENT: use patient planner flag maxCutBack: 3 # maximum cut back level (0: 1, 1: 0.5, 2: 0.25, etc) maxStaggeredIter: 10 # max number of field level staggered iterations - memory_efficient: 1 # Precalculate Gamma-operator (81 double per point) update_gamma: false # Update Gamma-operator with current dPdF (not possible if memory_efficient=1) divergence_correction: 2 # Use size-independent divergence criterion derivative: continuous # Approximation used for derivatives in Fourier space - solver: Basic # Type of spectral solver (BasicPETSc/Polarisation/FEM) petsc_options: -snes_type ngmres -snes_ngmres_anderson # PetSc solver options alpha: 1.0 # polarization scheme parameter 0.0 < alpha < 2.0. alpha = 1.0 ==> AL scheme, alpha = 2.0 ==> accelerated scheme beta: 1.0 # polarization scheme parameter 0.0 < beta < 2.0. beta = 1.0 ==> AL scheme, beta = 2.0 ==> accelerated scheme diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index 01b4c034d..4961b99d4 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -111,7 +111,7 @@ subroutine CPFEM_init !------------------------------------------------------------------------------ ! read debug options - debug_CPFEM => config_debug%get('cpfem',defaultVal=emptyList) + debug_CPFEM => config_debug%get('CPFEM',defaultVal=emptyList) debugCPFEM%basic = debug_CPFEM%contains('basic') debugCPFEM%extensive = debug_CPFEM%contains('extensive') debugCPFEM%selective = debug_CPFEM%contains('selective') diff --git a/src/phase.f90 b/src/phase.f90 index 5a9eaa518..9470ab8af 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -346,17 +346,17 @@ subroutine phase_init print'(/,a)', ' <<<+- phase init -+>>>'; flush(IO_STDOUT) - debug_constitutive => config_debug%get('constitutive', defaultVal=emptyList) - debugConstitutive%basic = debug_constitutive%contains('basic') - debugConstitutive%extensive = debug_constitutive%contains('extensive') - debugConstitutive%selective = debug_constitutive%contains('selective') - debugConstitutive%element = config_debug%get_asInt('element',defaultVal = 1) - debugConstitutive%ip = config_debug%get_asInt('integrationpoint',defaultVal = 1) - debugConstitutive%grain = config_debug%get_asInt('grain',defaultVal = 1) + debug_constitutive => config_debug%get('phase', defaultVal=emptyList) + debugConstitutive%basic = debug_constitutive%contains('basic') + debugConstitutive%extensive = debug_constitutive%contains('extensive') + debugConstitutive%selective = debug_constitutive%contains('selective') + debugConstitutive%element = config_debug%get_asInt('element', defaultVal = 1) + debugConstitutive%ip = config_debug%get_asInt('integrationpoint',defaultVal = 1) + debugConstitutive%grain = config_debug%get_asInt('constituent', defaultVal = 1) materials => config_material%get('material') - phases => config_material%get('phase') + phases => config_material%get('phase') call mechanical_init(materials,phases) call damage_init From ac310ee760796d44fec4101bda4e2a79a8fd0025 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 19:54:10 +0100 Subject: [PATCH 029/219] elastic constants with source --- examples/config/Phase_Nonlocal_Aluminum.config | 4 ---- examples/config/Phase_Nonlocal_Nickel.config | 3 --- .../config/phase/mechanical/elastic/Aluminum.yaml | 4 ---- .../config/phase/mechanical/elastic/Hooke_Al.yaml | 12 ++++++++++++ .../config/phase/mechanical/elastic/Hooke_Au.yaml | 12 ++++++++++++ .../config/phase/mechanical/elastic/Hooke_Ni.yaml | 12 ++++++++++++ .../phase/mechanical/elastic/Hooke_cpTi.yaml | 15 +++++++++++++++ src/phase_mechanical.f90 | 2 +- src/phase_mechanical_plastic_nonlocal.f90 | 4 +--- 9 files changed, 53 insertions(+), 15 deletions(-) delete mode 100644 examples/config/phase/mechanical/elastic/Aluminum.yaml create mode 100644 examples/config/phase/mechanical/elastic/Hooke_Al.yaml create mode 100644 examples/config/phase/mechanical/elastic/Hooke_Au.yaml create mode 100644 examples/config/phase/mechanical/elastic/Hooke_Ni.yaml create mode 100644 examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml diff --git a/examples/config/Phase_Nonlocal_Aluminum.config b/examples/config/Phase_Nonlocal_Aluminum.config index 2af3a2b8b..500dcf69d 100644 --- a/examples/config/Phase_Nonlocal_Aluminum.config +++ b/examples/config/Phase_Nonlocal_Aluminum.config @@ -25,10 +25,6 @@ plasticity nonlocal lattice_structure fcc Nslip 12 # number of slip systems -c11 106.75e9 # elastic constants -c12 60.41e9 -c44 28.34e9 - burgers 2.86e-10 # Burgers vector in m rhoSglEdgePos0 0.25e10 # Initial positive edge single dislocation density in m/m**3 (per slip family) rhoSglEdgeNeg0 0.25e10 # Initial negative edge single dislocation density in m/m**3 (per slip family) diff --git a/examples/config/Phase_Nonlocal_Nickel.config b/examples/config/Phase_Nonlocal_Nickel.config index ab6505c50..c3814adeb 100644 --- a/examples/config/Phase_Nonlocal_Nickel.config +++ b/examples/config/Phase_Nonlocal_Nickel.config @@ -24,9 +24,6 @@ plasticity nonlocal lattice_structure fcc Nslip 12 # number of slip systems per family -c11 246.5e9 -c12 147.3e9 -c44 124.7e9 burgers 2.48e-10 # Burgers vector in m rhoSglEdgePos0 6e10 # Initial positive edge single dislocation density in m/m**3 rhoSglEdgeNeg0 6e10 # Initial negative edge single dislocation density in m/m**3 diff --git a/examples/config/phase/mechanical/elastic/Aluminum.yaml b/examples/config/phase/mechanical/elastic/Aluminum.yaml deleted file mode 100644 index a1fa22a97..000000000 --- a/examples/config/phase/mechanical/elastic/Aluminum.yaml +++ /dev/null @@ -1,4 +0,0 @@ -Aluminum: - lattice: cF - mechanical: - elastic: {C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9, type: hooke} diff --git a/examples/config/phase/mechanical/elastic/Hooke_Al.yaml b/examples/config/phase/mechanical/elastic/Hooke_Al.yaml new file mode 100644 index 000000000..fd3a5ddc2 --- /dev/null +++ b/examples/config/phase/mechanical/elastic/Hooke_Al.yaml @@ -0,0 +1,12 @@ +Al: + lattice: cF + mechanical: + elastic: + type: Hooke + references: + - J. Vallin et al., + Journal of Applied Physics 35(6), 1825-1826, 1964, + https://doi.org/10.1063/1.1713749 + C_11: 107.3e9 + C_12: 60.8e9 + C_44: 28.3e9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Au.yaml b/examples/config/phase/mechanical/elastic/Hooke_Au.yaml new file mode 100644 index 000000000..8a3249e15 --- /dev/null +++ b/examples/config/phase/mechanical/elastic/Hooke_Au.yaml @@ -0,0 +1,12 @@ +Au: + lattice: cF + mechanical: + elastic: + type: Hooke + references: + - J.P. Hirth and J. Lothe, + Theory of Dislocations, 1982, + John Wiley & Sons + C_11: 186e9 + C_12: 157e9 + C_44: 42e9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml b/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml new file mode 100644 index 000000000..bbfd867e5 --- /dev/null +++ b/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml @@ -0,0 +1,12 @@ +Ni: + lattice: cF + mechanical: + elastic: + type: Hooke + references: + - J.P. Hirth and J. Lothe, + Theory of Dislocations, 1982, + John Wiley & Sons + C_11: 246.5e9 + C_12: 147.3e9 + C_44: 124.7e9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml b/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml new file mode 100644 index 000000000..f2936d390 --- /dev/null +++ b/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml @@ -0,0 +1,15 @@ +cpTi: + lattice: hP + c/a: 1.587 + mechanical: + elastic: + type: Hooke + references: + - L. Wang et al., + Acta Materialia 132, 598-610, 2017, + https://doi.org/10.1016/j.actamat.2017.05.015 + C_11: 162.4e9 + C_33: 181.6e9 + C_44: 47.2e9 + C_12: 92e9 + C_13: 69e9 diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index 58f0f831c..d692ac4dc 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -254,7 +254,7 @@ module subroutine mechanical_init(materials,phases) output_constituent(ph)%label = mech%get_asStrings('output',defaultVal=emptyStringArray) #endif elastic => mech%get('elastic') - if(elastic%get_asString('type') == 'hooke') then + if (IO_lc(elastic%get_asString('type')) == 'hooke') then ! accept small letter h for the moment phase_elasticity(ph) = ELASTICITY_HOOKE_ID else call IO_error(200,ext_msg=elastic%get_asString('type')) diff --git a/src/phase_mechanical_plastic_nonlocal.f90 b/src/phase_mechanical_plastic_nonlocal.f90 index d884f5117..e4e008fab 100644 --- a/src/phase_mechanical_plastic_nonlocal.f90 +++ b/src/phase_mechanical_plastic_nonlocal.f90 @@ -1671,7 +1671,6 @@ pure subroutine kinetics(v, dv_dtau, dv_dtauNS, tau, tauNS, tauThreshold, c, Tem dv_dtauNS !< velocity derivative with respect to resolved shear stress (including non Schmid contributions) integer :: & - ns, & !< short notation for the total number of active slip systems s !< index of my current slip system real(pReal) :: & tauRel_P, & @@ -1697,12 +1696,11 @@ pure subroutine kinetics(v, dv_dtau, dv_dtauNS, tau, tauNS, tauThreshold, c, Tem mobility !< dislocation mobility associate(prm => param(ph)) - ns = prm%sum_N_sl v = 0.0_pReal dv_dtau = 0.0_pReal dv_dtauNS = 0.0_pReal - do s = 1,ns + do s = 1,prm%sum_N_sl if (abs(tau(s)) > tauThreshold(s)) then !* Peierls contribution From 3a74270946ffa02334a8881d02b4d57de90e920d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 20:21:20 +0100 Subject: [PATCH 030/219] new style --- examples/grid/20grains.seeds | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/grid/20grains.seeds b/examples/grid/20grains.seeds index d6b1c4f65..376e4bc6f 100644 --- a/examples/grid/20grains.seeds +++ b/examples/grid/20grains.seeds @@ -1,6 +1,3 @@ -3 header -grid a 16 b 16 c 16 -random seed 0 1_pos 2_pos 3_pos 1_euler 2_euler 3_euler 0.375488 0.161813 0.891040 197.572861 16.816409 129.422844 0.187988 0.849313 0.953540 257.468172 53.250534 157.331503 From 9fd244d8a058e4b36a7417c695f4e7431b49faab Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 20:56:55 +0100 Subject: [PATCH 031/219] cleaning --- .../phase/mechanical/elastic/Hooke_Al.yaml | 2 +- .../phase/mechanical/elastic/Hooke_Au.yaml | 2 +- .../phase/mechanical/elastic/Hooke_Ni.yaml | 2 +- .../phase/mechanical/elastic/Hooke_cpTi.yaml | 4 +- processing/pre/mentat_pbcOnBoxMesh.py | 8 ++-- python/damask/__init__.py | 3 -- python/damask/_test.py | 4 +- python/damask/util.py | 45 +------------------ python/tests/test_util.py | 3 -- 9 files changed, 11 insertions(+), 62 deletions(-) diff --git a/examples/config/phase/mechanical/elastic/Hooke_Al.yaml b/examples/config/phase/mechanical/elastic/Hooke_Al.yaml index fd3a5ddc2..3a6f06a23 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Al.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Al.yaml @@ -3,7 +3,7 @@ Al: mechanical: elastic: type: Hooke - references: + references: - J. Vallin et al., Journal of Applied Physics 35(6), 1825-1826, 1964, https://doi.org/10.1063/1.1713749 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Au.yaml b/examples/config/phase/mechanical/elastic/Hooke_Au.yaml index 8a3249e15..b2d6cde08 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Au.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Au.yaml @@ -3,7 +3,7 @@ Au: mechanical: elastic: type: Hooke - references: + references: - J.P. Hirth and J. Lothe, Theory of Dislocations, 1982, John Wiley & Sons diff --git a/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml b/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml index bbfd867e5..0b032c350 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml @@ -3,7 +3,7 @@ Ni: mechanical: elastic: type: Hooke - references: + references: - J.P. Hirth and J. Lothe, Theory of Dislocations, 1982, John Wiley & Sons diff --git a/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml b/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml index f2936d390..2c2e3261d 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml @@ -2,9 +2,9 @@ cpTi: lattice: hP c/a: 1.587 mechanical: - elastic: + elastic: type: Hooke - references: + references: - L. Wang et al., Acta Materialia 132, 598-610, 2017, https://doi.org/10.1016/j.actamat.2017.05.015 diff --git a/processing/pre/mentat_pbcOnBoxMesh.py b/processing/pre/mentat_pbcOnBoxMesh.py index 4a4f3d642..5a4891002 100755 --- a/processing/pre/mentat_pbcOnBoxMesh.py +++ b/processing/pre/mentat_pbcOnBoxMesh.py @@ -76,10 +76,10 @@ def asMFD(mfd_data): elif type(num) == float: result += '{:20.12e}'.format(num) else: - damask.util.croak('WARNING: encountered unknown type: ' + str(type(el))) + print(f'WARNING: encountered unknown type: {type(el)}') result += '\n' else: - damask.util.croak('WARNING: encountered unknown type: ' + str(type(el))) + print(f'WARNING: encountered unknown type: {type(el)}') if section['uid'] > 0: result += '=end=\n' return result.strip() @@ -244,9 +244,9 @@ if remote: py_mentat.py_send('*save_as_model "{}" yes'.format(filenames[0])) py_mentat.py_get_int("nnodes()") except py_mentat.InputError as err: - damask.util.croak('{}. Try Tools/Python/"Run as Separate Process" & "Initiate".'.format(err)) + print(f'{err}. Try Tools/Python/"Run as Separate Process" & "Initiate".') sys.exit(-1) - damask.util.croak( 'connected...') + print( 'connected...') for name in filenames: while remote and not os.path.exists(name): time.sleep(0.5) diff --git a/python/damask/__init__.py b/python/damask/__init__.py index e356d0bc4..a421e29c4 100644 --- a/python/damask/__init__.py +++ b/python/damask/__init__.py @@ -33,9 +33,6 @@ from ._configmaterial import ConfigMaterial # noqa from ._grid import Grid # noqa from ._result import Result # noqa - - # deprecated from ._asciitable import ASCIItable # noqa from ._test import Test # noqa -from .util import extendableOption # noqa diff --git a/python/damask/_test.py b/python/damask/_test.py index f8fb24cca..e62b9e8cc 100644 --- a/python/damask/_test.py +++ b/python/damask/_test.py @@ -53,8 +53,7 @@ class Test: self.dirBase = os.path.dirname(os.path.realpath(sys.modules[self.__class__.__module__].__file__)) - self.parser = OptionParser(option_class=damask.extendableOption, - description = f'{self.description} (Test class version: {damask.version})', + self.parser = OptionParser(description = f'{self.description} (Test class version: {damask.version})', usage = './test.py [options]') self.parser.add_option("-k", "--keep", action = "store_true", @@ -70,7 +69,6 @@ class Test: help = "show all test variants without actual calculation") self.parser.add_option("-s", "--select", dest = "select", - action = 'extend', metavar = '', help = "run test(s) of given name only") self.parser.set_defaults(keep = self.keep, accept = self.accept, diff --git a/python/damask/util.py b/python/damask/util.py index 56143cc5e..cdedd73ed 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -6,7 +6,6 @@ import shlex import re import fractions from functools import reduce -from optparse import Option import numpy as np import h5py @@ -16,7 +15,6 @@ from . import version # limit visibility __all__=[ 'srepr', - 'croak', 'report', 'emph','deemph','warn','strikeout', 'execute', @@ -25,7 +23,6 @@ __all__=[ 'project_stereographic', 'hybrid_IA', 'return_message', - 'extendableOption', 'execution_stamp', 'shapeshifter', 'shapeblender', 'extend_docstring', 'extended_docstring', @@ -54,25 +51,6 @@ def srepr(arg,glue = '\n'): return arg if isinstance(arg,str) else repr(arg) -def croak(what, newline = True): - """ - Write formated to stderr. - - DEPRECATED - - Parameters - ---------- - what : str or iterable - Content to be displayed. - newline : bool, optional - Separate items of what by newline. Defaults to True. - - """ - if what is not None: - sys.stderr.write(srepr(what,glue = '\n') + ('\n' if newline else '')) - sys.stderr.flush() - - def report(who = None, what = None): """ @@ -81,7 +59,7 @@ def report(who = None, DEPRECATED """ - croak( (emph(who)+': ' if who is not None else '') + (what if what is not None else '') + '\n' ) + print( (emph(who)+': ' if who is not None else '') + (what if what is not None else '') + '\n' ) def emph(what): @@ -428,27 +406,6 @@ def DREAM3D_cell_data_group(fname): #################################################################################################### # Classes #################################################################################################### -class extendableOption(Option): - """ - Used for definition of new option parser action 'extend', which enables to take multiple option arguments. - - Adopted from online tutorial http://docs.python.org/library/optparse.html - DEPRECATED - """ - - ACTIONS = Option.ACTIONS + ("extend",) - STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",) - TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",) - ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",) - - def take_action(self, action, dest, opt, value, values, parser): - if action == "extend": - lvalue = value.split(",") - values.ensure_value(dest, []).extend(lvalue) - else: - Option.take_action(self, action, dest, opt, value, values, parser) - - class _ProgressBar: """ Report progress of an interation as a status bar. diff --git a/python/tests/test_util.py b/python/tests/test_util.py index 93044b31d..b96908a9a 100644 --- a/python/tests/test_util.py +++ b/python/tests/test_util.py @@ -23,9 +23,6 @@ class TestUtil: with pytest.raises(RuntimeError): util.execute('/bin/false') - def test_croak(self): - util.croak('Burp!') - @pytest.mark.parametrize('input,output', [ ([0,-2],[0,-1]), From 4d046e4e166bcefdb5eef3dcb690466eecbda417 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 26 Mar 2021 21:16:11 +0100 Subject: [PATCH 032/219] no plastic model as default --- src/phase_mechanical_plastic.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/phase_mechanical_plastic.f90 b/src/phase_mechanical_plastic.f90 index 5e0dc49a4..3e9772a87 100644 --- a/src/phase_mechanical_plastic.f90 +++ b/src/phase_mechanical_plastic.f90 @@ -450,8 +450,8 @@ function plastic_active(plastic_label) result(active_plastic) do ph = 1, phases%length phase => phases%get(ph) mech => phase%get('mechanical') - pl => mech%get('plastic') - if(pl%get_asString('type') == plastic_label) active_plastic(ph) = .true. + pl => mech%get('plastic',defaultVal = emptyDict) + if(pl%get_asString('type',defaultVal='none') == plastic_label) active_plastic(ph) = .true. enddo end function plastic_active From 22195faecc970dbd3d0ad7270da477d2cd158302 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 06:12:25 +0100 Subject: [PATCH 033/219] ':' causes problem in Fortran YAML parser --- examples/config/phase/mechanical/elastic/Hooke_Al.yaml | 2 +- examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/config/phase/mechanical/elastic/Hooke_Al.yaml b/examples/config/phase/mechanical/elastic/Hooke_Al.yaml index 3a6f06a23..583ad183d 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Al.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Al.yaml @@ -6,7 +6,7 @@ Al: references: - J. Vallin et al., Journal of Applied Physics 35(6), 1825-1826, 1964, - https://doi.org/10.1063/1.1713749 + 10.1063/1.1713749 C_11: 107.3e9 C_12: 60.8e9 C_44: 28.3e9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml b/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml index 2c2e3261d..a3ba24d6c 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml @@ -7,7 +7,7 @@ cpTi: references: - L. Wang et al., Acta Materialia 132, 598-610, 2017, - https://doi.org/10.1016/j.actamat.2017.05.015 + 10.1016/j.actamat.2017.05.015 C_11: 162.4e9 C_33: 181.6e9 C_44: 47.2e9 From 111a1a76c6735db70eb10d66b2195c43ba2562fb Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 07:35:49 +0100 Subject: [PATCH 034/219] cleaning --- processing/pre/mentat_pbcOnBoxMesh.py | 4 +- processing/pre/mentat_spectralBox.py | 2 +- python/damask/_test.py | 4 +- python/damask/util.py | 130 +++++++++++--------------- python/tests/test_Grid.py | 4 + 5 files changed, 61 insertions(+), 83 deletions(-) diff --git a/processing/pre/mentat_pbcOnBoxMesh.py b/processing/pre/mentat_pbcOnBoxMesh.py index 5a4891002..1cf18eeda 100755 --- a/processing/pre/mentat_pbcOnBoxMesh.py +++ b/processing/pre/mentat_pbcOnBoxMesh.py @@ -236,7 +236,7 @@ if remote: sys.path.append(str(damask.solver.Marc().library_path)) import py_mentat - damask.util.report(scriptName, 'waiting to connect...') + print(scriptName+': waiting to connect...') filenames = [os.path.join(tempfile._get_default_tempdir(), next(tempfile._get_candidate_names()) + '.mfd')] try: py_mentat.py_connect('',options.port) @@ -251,7 +251,7 @@ if remote: for name in filenames: while remote and not os.path.exists(name): time.sleep(0.5) with open( name,'r') if name is not None else sys.stdin as fileIn: - damask.util.report(scriptName, name) + print(scriptName+': '+name) mfd = parseMFD(fileIn) add_servoLinks(mfd,[options.x,options.y,options.z]) diff --git a/processing/pre/mentat_spectralBox.py b/processing/pre/mentat_spectralBox.py index d2c966f3f..72206a8f4 100755 --- a/processing/pre/mentat_spectralBox.py +++ b/processing/pre/mentat_spectralBox.py @@ -194,7 +194,7 @@ if options.port is not None: if filenames == []: filenames = [None] for name in filenames: - damask.util.report(scriptName,name) + print(scriptName+': '+name) geom = damask.Grid.load(StringIO(''.join(sys.stdin.read())) if name is None else name) material = geom.material.flatten(order='F') diff --git a/python/damask/_test.py b/python/damask/_test.py index e62b9e8cc..d5c946034 100644 --- a/python/damask/_test.py +++ b/python/damask/_test.py @@ -270,10 +270,10 @@ class Test: raise FileNotFoundError - def execute_inCurrentDir(self,cmd,streamIn=None,env=None): + def execute_inCurrentDir(self,cmd,env=None): logging.info(cmd) - out,error = damask.util.execute(cmd,streamIn,self.dirCurrent()) + out,error = damask.util.execute(cmd,self.dirCurrent()) logging.info(error) logging.debug(out) diff --git a/python/damask/util.py b/python/damask/util.py index cdedd73ed..5f2a8b1ff 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -15,7 +15,6 @@ from . import version # limit visibility __all__=[ 'srepr', - 'report', 'emph','deemph','warn','strikeout', 'execute', 'show_progress', @@ -29,6 +28,21 @@ __all__=[ 'DREAM3D_base_group', 'DREAM3D_cell_data_group' ] +# https://svn.blender.org/svnroot/bf-blender/trunk/blender/build_files/scons/tools/bcolors.py +# https://stackoverflow.com/questions/287871 +_colors = { + 'header' : '\033[95m', + 'OK_blue': '\033[94m', + 'OK_green': '\033[92m', + 'warning': '\033[93m', + 'fail': '\033[91m', + 'end_color': '\033[0m', + 'bold': '\033[1m', + 'dim': '\033[2m', + 'underline': '\033[4m', + 'crossout': '\033[9m' + } + #################################################################################################### # Functions #################################################################################################### @@ -51,38 +65,24 @@ def srepr(arg,glue = '\n'): return arg if isinstance(arg,str) else repr(arg) -def report(who = None, - what = None): - """ - Report script and file name. - - DEPRECATED - - """ - print( (emph(who)+': ' if who is not None else '') + (what if what is not None else '') + '\n' ) - - def emph(what): """Formats string with emphasis.""" - return bcolors.BOLD+srepr(what)+bcolors.ENDC + return _colors['bold']+srepr(what)+_colors['end_color'] def deemph(what): """Formats string with deemphasis.""" - return bcolors.DIM+srepr(what)+bcolors.ENDC + return _colors['dim']+srepr(what)+_colors['end_color'] def warn(what): """Formats string for warning.""" - return bcolors.WARNING+emph(what)+bcolors.ENDC + return _colors['warning']+emph(what)+_colors['end_color'] def strikeout(what): """Formats string as strikeout.""" - return bcolors.CROSSOUT+srepr(what)+bcolors.ENDC + return _colors['crossout']+srepr(what)+_colors['end_color'] -def execute(cmd, - stream_in = None, - wd = './', - env = None): +def execute(cmd,wd='./',env=None): """ Execute command. @@ -90,33 +90,26 @@ def execute(cmd, ---------- cmd : str Command to be executed. - stream_in : file object, optional - Input (via pipe) for executed process. wd : str, optional Working directory of process. Defaults to ./ . env : dict, optional Environment for execution. """ - initialPath = os.getcwd() - myEnv = os.environ if env is None else env - os.chdir(wd) print(f"executing '{cmd}' in '{wd}'") - process = subprocess.Popen(shlex.split(cmd), - stdout = subprocess.PIPE, - stderr = subprocess.PIPE, - stdin = subprocess.PIPE, - env = myEnv) - stdout, stderr = [i for i in (process.communicate() if stream_in is None - else process.communicate(stream_in.read().encode('utf-8')))] - os.chdir(initialPath) - stdout = stdout.decode('utf-8').replace('\x08','') - stderr = stderr.decode('utf-8').replace('\x08','') + process = subprocess.run(shlex.split(cmd), + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + env = os.environ if env is None else env, + cwd = wd, + encoding = 'utf-8') + if process.returncode != 0: - print(stdout) - print(stderr) + print(process.stdout) + print(process.stderr) raise RuntimeError(f"'{cmd}' failed with returncode {process.returncode}") - return stdout, stderr + + return process.stdout, process.stderr def show_progress(iterable,N_iter=None,prefix='',bar_length=50): @@ -403,9 +396,30 @@ def DREAM3D_cell_data_group(fname): return cell_data_group + #################################################################################################### # Classes #################################################################################################### +class return_message: + """Object with formatted return message.""" + + def __init__(self,message): + """ + Sets return message. + + Parameters + ---------- + message : str or list of str + message for output to screen + + """ + self.message = message + + def __repr__(self): + """Return message suitable for interactive shells.""" + return srepr(self.message) + + class _ProgressBar: """ Report progress of an interation as a status bar. @@ -454,43 +468,3 @@ class _ProgressBar: if iteration == self.total - 1: sys.stderr.write('\n') sys.stderr.flush() - - -class bcolors: - """ - ASCII colors. - - https://svn.blender.org/svnroot/bf-blender/trunk/blender/build_files/scons/tools/bcolors.py - https://stackoverflow.com/questions/287871 - """ - - HEADER = '\033[95m' - OKBLUE = '\033[94m' - OKGREEN = '\033[92m' - WARNING = '\033[93m' - FAIL = '\033[91m' - ENDC = '\033[0m' - BOLD = '\033[1m' - DIM = '\033[2m' - UNDERLINE = '\033[4m' - CROSSOUT = '\033[9m' - - -class return_message: - """Object with formatted return message.""" - - def __init__(self,message): - """ - Sets return message. - - Parameters - ---------- - message : str or list of str - message for output to screen - - """ - self.message = message - - def __repr__(self): - """Return message suitable for interactive shells.""" - return srepr(self.message) diff --git a/python/tests/test_Grid.py b/python/tests/test_Grid.py index 7e94686ee..51b4f1d29 100644 --- a/python/tests/test_Grid.py +++ b/python/tests/test_Grid.py @@ -431,6 +431,10 @@ class TestGrid: reference = VTK.load(ref_path/f'get_grain_boundaries_8g12x15x20_{"".join(direction)}_{periodic}.vtu') assert current.__repr__() == reference.__repr__() + @pytest.mark.parametrize('directions',[(1,2,'y'),('a','b','x'),[1]]) + def test_get_grain_boundaries_invalid(self,default,directions): + with pytest.raises(ValueError): + default.get_grain_boundaries(directions=directions) def test_load_DREAM3D(self,ref_path): grain = Grid.load_DREAM3D(ref_path/'2phase_irregularGrid.dream3d','FeatureIds') From be9e00347b2e6bf6681e7ca66ce13aea55e28a6e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 10:10:35 +0100 Subject: [PATCH 035/219] cleaning dropped support for legacy table --- Makefile | 8 ++-- python/damask/_colormap.py | 10 ++--- python/damask/_config.py | 2 +- python/damask/_configmaterial.py | 19 ++++++++- python/damask/_grid.py | 11 ++++- python/damask/_orientation.py | 39 ++++++++++------- python/damask/_result.py | 4 +- python/damask/_rotation.py | 26 ++++++------ python/damask/_table.py | 42 ++++++------------- python/damask/_vtk.py | 2 +- python/damask/util.py | 12 +++--- .../tests/reference/Orientation/cF_Bain.txt | 1 - python/tests/reference/Orientation/cF_GT.txt | 1 - .../reference/Orientation/cF_GT_prime.txt | 1 - python/tests/reference/Orientation/cF_KS.txt | 1 - python/tests/reference/Orientation/cF_NW.txt | 1 - .../tests/reference/Orientation/cF_Pitsch.txt | 1 - .../tests/reference/Orientation/cI_Bain.txt | 1 - python/tests/reference/Orientation/cI_GT.txt | 1 - .../reference/Orientation/cI_GT_prime.txt | 1 - python/tests/reference/Orientation/cI_KS.txt | 1 - python/tests/reference/Orientation/cI_NW.txt | 1 - .../tests/reference/Orientation/cI_Pitsch.txt | 1 - python/tests/test_Table.py | 7 ---- 24 files changed, 98 insertions(+), 96 deletions(-) diff --git a/Makefile b/Makefile index d38966bc5..dfbcbd5ae 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,9 @@ SHELL = /bin/sh -######################################################################################## -# Makefile for the installation of DAMASK -######################################################################################## + +################################################################################################### +# One-command-build invoking CMake (meant for developers, should not be part of the distribution) +################################################################################################### + .PHONY: all all: grid mesh diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index 639a5a04c..de63508b3 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -39,20 +39,20 @@ class Colormap(mpl.colors.ListedColormap): """ def __add__(self,other): - """Concatenate colormaps.""" + """Concatenate.""" return Colormap(np.vstack((self.colors,other.colors)), f'{self.name}+{other.name}') def __iadd__(self,other): - """Concatenate colormaps.""" + """Concatenate (in-place).""" return self.__add__(other) def __invert__(self): - """Return inverted colormap.""" + """Reverse.""" return self.reversed() def __repr__(self): - """Show colormap as matplotlib figure.""" + """Show as matplotlib figure.""" fig = plt.figure(self.name,figsize=(5,.5)) ax1 = fig.add_axes([0, 0, 1, 1]) ax1.set_axis_off() @@ -207,7 +207,7 @@ class Colormap(mpl.colors.ListedColormap): def reversed(self,name=None): """ - Make a reversed instance of the colormap. + Reverse. Parameters ---------- diff --git a/python/damask/_config.py b/python/damask/_config.py index 5be1d973c..989f28fcd 100644 --- a/python/damask/_config.py +++ b/python/damask/_config.py @@ -31,7 +31,7 @@ class NiceDumper(yaml.SafeDumper): return super().represent_data(data) def ignore_aliases(self, data): - """No references.""" + """Do not use references to existing objects.""" return True class Config(dict): diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index fb9b41932..a5fe837ee 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -9,14 +9,29 @@ from . import Orientation from . import util class ConfigMaterial(Config): - """Material configuration.""" + """ + Material configuration. + + Manipulate material configurations for storage in YAML format. + A complete material configuration file has the entries 'material', + 'phase', and 'homogenization'. For use in DAMASK, it needs to be + stored as 'material.yaml'. + """ _defaults = {'material': [], 'homogenization': {}, 'phase': {}} def __init__(self,d=_defaults): - """Initialize object with default dictionary keys.""" + """ + New material configuration. + + Parameters + ---------- + d : dictionary, optional + Initial content. Defaults to empty material, homogenization, and phase entries. + + """ super().__init__(d) diff --git a/python/damask/_grid.py b/python/damask/_grid.py index a76f7f2c4..18c9b0d25 100644 --- a/python/damask/_grid.py +++ b/python/damask/_grid.py @@ -17,11 +17,18 @@ from . import Rotation class Grid: - """Geometry definition for grid solvers.""" + """ + Geometry definition for grid solvers. + + Create and manipulate geometry definitions for storage as VTK + rectiliear grid files ('.vtr' extension). A grid contains the + material ID (referring to the entry in 'material.yaml') and + the physical size. + """ def __init__(self,material,size,origin=[0.0,0.0,0.0],comments=[]): """ - New grid definition from array of materials, size, and origin. + New geometry definition for grid solvers. Parameters ---------- diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index f05f47544..bbb682e82 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -47,19 +47,30 @@ class Orientation(Rotation): The Bravais lattice is one of Orientation.lattice_symmetries: - - aP : triclinic primitive - - mP : monoclinic primitive - - mS : ... base-centered - - oP : orthorhombic primitive - - oS : ... base-centered - - oI : ... body-centered - - oF : ... face-centered - - tP : tetragonal primitive - - tI : ... body-centered - - hP : hexagonal primitive - - cP : cubic primitive - - cI : ... body-centered - - cF : ... face-centered + - triclinic + - aP : primitive + + - monoclininic + - mP : primitive + - mS : base-centered + + - orthorhombic + - oP : primitive + - oS : base-centered + - oI : body-centered + - oF : face-centered + + - tetragonal + - tP : primitive + - tI : body-centered + + - hexagonal + - hP : primitive + + - cubic + - cP : primitive + - cI : body-centered + - cF : face-centered and inherits the corresponding crystal family. Specifying a Bravais lattice, compared to just the crystal family, @@ -111,7 +122,7 @@ class Orientation(Rotation): alpha = None,beta = None,gamma = None, degrees = False): """ - Initialize orientation object. + New orientation. Parameters ---------- diff --git a/python/damask/_result.py b/python/damask/_result.py index f247a8d07..415ddded9 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -26,14 +26,14 @@ h5py3 = h5py.__version__[0] == '3' class Result: """ - Read and write to DADF5 files. + Manipulate and read DADF5 files. DADF5 (DAMASK HDF5) files contain DAMASK results. """ def __init__(self,fname): """ - Open an existing DADF5 file. + New result view bound to a HDF5 file. Parameters ---------- diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 40078e4d5..8d8a13d99 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -51,7 +51,7 @@ class Rotation: def __init__(self,rotation = np.array([1.0,0.0,0.0,0.0])): """ - Initialize rotation object. + New rotation. Parameters ---------- @@ -140,7 +140,7 @@ class Rotation: def __len__(self): - """Length of leading/leftmost dimension of Rotation array.""" + """Length of leading/leftmost dimension of array.""" return 0 if self.shape == () else self.shape[0] @@ -180,7 +180,7 @@ class Rotation: def __mul__(self,other): """ - Compose this rotation with other. + Compose with other. Parameters ---------- @@ -206,7 +206,7 @@ class Rotation: def __imul__(self,other): """ - Compose this rotation with other (in-place). + Compose with other (in-place). Parameters ---------- @@ -219,7 +219,7 @@ class Rotation: def __truediv__(self,other): """ - Compose this rotation with inverse of other. + Compose with inverse of other. Parameters ---------- @@ -239,7 +239,7 @@ class Rotation: def __itruediv__(self,other): """ - Compose this rotation with inverse of other (in-place). + Compose with inverse of other (in-place). Parameters ---------- @@ -252,7 +252,7 @@ class Rotation: def __matmul__(self,other): """ - Rotation of vector, second order tensor, or fourth order tensor. + Rotate vector, second order tensor, or fourth order tensor. Parameters ---------- @@ -301,7 +301,7 @@ class Rotation: def append(self,other): """ - Extend rotation array along first dimension with other array(s). + Extend array along first dimension with other array(s). Parameters ---------- @@ -313,19 +313,19 @@ class Rotation: def flatten(self,order = 'C'): - """Flatten quaternion array.""" + """Flatten array.""" return self.copy(rotation=self.quaternion.reshape((-1,4),order=order)) def reshape(self,shape,order = 'C'): - """Reshape quaternion array.""" + """Reshape array.""" if isinstance(shape,(int,np.integer)): shape = (shape,) return self.copy(rotation=self.quaternion.reshape(tuple(shape)+(4,),order=order)) def broadcast_to(self,shape,mode = 'right'): """ - Broadcast quaternion array to shape. + Broadcast array. Parameters ---------- @@ -343,7 +343,7 @@ class Rotation: def average(self,weights = None): """ - Average rotations along last dimension. + Average along last array dimension. Parameters ---------- @@ -382,7 +382,7 @@ class Rotation: def misorientation(self,other): """ - Calculate misorientation from self to other Rotation. + Calculate misorientation to other Rotation. Parameters ---------- diff --git a/python/damask/_table.py b/python/damask/_table.py index ee64ba017..fef84cca5 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -7,7 +7,7 @@ import numpy as np from . import util class Table: - """Store spreadsheet-like data.""" + """Manipulate multi-dimensional spreadsheet-like data.""" def __init__(self,data,shapes,comments=None): """ @@ -77,13 +77,11 @@ class Table: """ Load from ASCII table file. - In legacy style, the first line indicates the number of - subsequent header lines as "N header", with the last header line being - interpreted as column labels. - Alternatively, initial comments are marked by '#', with the first non-comment line + Initial comments are marked by '#', the first non-comment line containing the column labels. - Vector data column labels are indicated by '1_v, 2_v, ..., n_v'. - Tensor data column labels are indicated by '3x3:1_T, 3x3:2_T, ..., 3x3:9_T'. + + - Vector data column labels are indicated by '1_v, 2_v, ..., n_v'. + - Tensor data column labels are indicated by '3x3:1_T, 3x3:2_T, ..., 3x3:9_T'. Parameters ---------- @@ -97,21 +95,13 @@ class Table: f = fname f.seek(0) - try: - N_comment_lines,keyword = f.readline().strip().split(maxsplit=1) - if keyword != 'header': - raise ValueError - else: - comments = [f.readline().strip() for i in range(1,int(N_comment_lines))] - labels = f.readline().split() - except ValueError: - f.seek(0) - comments = [] + f.seek(0) + comments = [] + line = f.readline().strip() + while line.startswith('#'): + comments.append(line.lstrip('#').strip()) line = f.readline().strip() - while line.startswith('#'): - comments.append(line.lstrip('#').strip()) - line = f.readline().strip() - labels = line.split() + labels = line.split() shapes = {} for label in labels: @@ -391,7 +381,7 @@ class Table: return dup - def save(self,fname,legacy=False): + def save(self,fname): """ Save as plain text file. @@ -399,9 +389,6 @@ class Table: ---------- fname : file, str, or pathlib.Path Filename or file for writing. - legacy : Boolean, optional - Write table in legacy style, indicating header lines by "N header" - in contrast to using comment sign ('#') at beginning of lines. """ seen = set() @@ -416,13 +403,10 @@ class Table: labels += [f'{util.srepr(self.shapes[l],"x")}:{i+1}_{l}' \ for i in range(np.prod(self.shapes[l]))] - header = ([f'{len(self.comments)+1} header'] + self.comments) if legacy else \ - [f'# {comment}' for comment in self.comments] - try: fhandle = open(fname,'w',newline='\n') except TypeError: fhandle = fname - for line in header + [' '.join(labels)]: fhandle.write(line+'\n') + fhandle.write('\n'.join([f'# {c}' for c in self.comments] + [' '.join(labels)])+'\n') self.data.to_csv(fhandle,sep=' ',na_rep='nan',index=False,header=False) diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index b9f237297..ebd2f39a6 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -22,7 +22,7 @@ class VTK: def __init__(self,vtk_data): """ - Initialize from vtk dataset. + New spatial visualization. Parameters ---------- diff --git a/python/damask/util.py b/python/damask/util.py index 5f2a8b1ff..902e0409c 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -153,10 +153,12 @@ def scale_to_coprime(v): """Denominator of the square of a number.""" return fractions.Fraction(x ** 2).limit_denominator(MAX_DENOMINATOR).denominator - def lcm(a, b): + def lcm(a,b): """Least common multiple.""" - # Python 3.9 provides math.lcm, see https://stackoverflow.com/questions/51716916. - return a * b // np.gcd(a, b) + try: + return np.lcm(a,b) # numpy > 1.18 + except AttributeError: + return a * b // np.gcd(a, b) m = (np.array(v) * reduce(lcm, map(lambda x: int(get_square_denominator(x)),v)) ** 0.5).astype(int) m = m//reduce(np.gcd,m) @@ -405,7 +407,7 @@ class return_message: def __init__(self,message): """ - Sets return message. + Set return message. Parameters ---------- @@ -429,7 +431,7 @@ class _ProgressBar: def __init__(self,total,prefix,bar_length): """ - Inititalize a progress bar to current time as basis for ETA estimation. + Set current time as basis for ETA estimation. Parameters ---------- diff --git a/python/tests/reference/Orientation/cF_Bain.txt b/python/tests/reference/Orientation/cF_Bain.txt index 876cf3888..ae06eb2fb 100644 --- a/python/tests/reference/Orientation/cF_Bain.txt +++ b/python/tests/reference/Orientation/cF_Bain.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 180.0 45.00000000000001 180.0 1 1 270.0 45.00000000000001 90.0 1 2 diff --git a/python/tests/reference/Orientation/cF_GT.txt b/python/tests/reference/Orientation/cF_GT.txt index cefae431a..e73885048 100644 --- a/python/tests/reference/Orientation/cF_GT.txt +++ b/python/tests/reference/Orientation/cF_GT.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 146.75362934444064 9.976439066337804 256.395594327347 1 1 356.59977719102034 43.39784965440254 12.173896584899929 1 2 diff --git a/python/tests/reference/Orientation/cF_GT_prime.txt b/python/tests/reference/Orientation/cF_GT_prime.txt index 44a9b25ec..3a9021912 100644 --- a/python/tests/reference/Orientation/cF_GT_prime.txt +++ b/python/tests/reference/Orientation/cF_GT_prime.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 166.39559432734697 9.976439066337804 236.75362934444058 1 1 352.1156357053931 43.82007387041961 14.074783631236542 1 2 diff --git a/python/tests/reference/Orientation/cF_KS.txt b/python/tests/reference/Orientation/cF_KS.txt index 93fdcf07e..d63442cf3 100644 --- a/python/tests/reference/Orientation/cF_KS.txt +++ b/python/tests/reference/Orientation/cF_KS.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 114.20342833932975 10.52877936550932 204.20342833932972 1 1 94.3573968784815 80.40593177313954 311.22729452432543 1 2 diff --git a/python/tests/reference/Orientation/cF_NW.txt b/python/tests/reference/Orientation/cF_NW.txt index cc9c95a05..d22b86e1b 100644 --- a/python/tests/reference/Orientation/cF_NW.txt +++ b/python/tests/reference/Orientation/cF_NW.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 96.91733794010702 83.13253115922213 314.5844440567886 1 1 173.082662059893 83.13253115922211 45.41555594321143 1 2 diff --git a/python/tests/reference/Orientation/cF_Pitsch.txt b/python/tests/reference/Orientation/cF_Pitsch.txt index aa0c32365..b18e5212b 100644 --- a/python/tests/reference/Orientation/cF_Pitsch.txt +++ b/python/tests/reference/Orientation/cF_Pitsch.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 135.41555594321144 83.13253115922213 173.082662059893 1 1 260.26438968275465 90.0 135.0 1 2 diff --git a/python/tests/reference/Orientation/cI_Bain.txt b/python/tests/reference/Orientation/cI_Bain.txt index e0bc4f6c7..0bb55aaef 100644 --- a/python/tests/reference/Orientation/cI_Bain.txt +++ b/python/tests/reference/Orientation/cI_Bain.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 0.0 45.00000000000001 0.0 1 1 90.0 45.00000000000001 270.0 1 2 diff --git a/python/tests/reference/Orientation/cI_GT.txt b/python/tests/reference/Orientation/cI_GT.txt index 5d5102698..c2805c3e4 100644 --- a/python/tests/reference/Orientation/cI_GT.txt +++ b/python/tests/reference/Orientation/cI_GT.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 283.60440567265294 9.976439066337804 33.24637065555936 1 1 167.8261034151001 43.397849654402556 183.40022280897963 1 2 diff --git a/python/tests/reference/Orientation/cI_GT_prime.txt b/python/tests/reference/Orientation/cI_GT_prime.txt index e398d3139..1d0f6c3c6 100644 --- a/python/tests/reference/Orientation/cI_GT_prime.txt +++ b/python/tests/reference/Orientation/cI_GT_prime.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 303.24637065555936 9.976439066337804 13.604405672652977 1 1 165.92521636876344 43.82007387041961 187.88436429460683 1 2 diff --git a/python/tests/reference/Orientation/cI_KS.txt b/python/tests/reference/Orientation/cI_KS.txt index 34b393358..b35a07fb8 100644 --- a/python/tests/reference/Orientation/cI_KS.txt +++ b/python/tests/reference/Orientation/cI_KS.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 335.7965716606702 10.528779365509317 65.79657166067024 1 1 228.77270547567446 80.40593177313953 85.64260312151849 1 2 diff --git a/python/tests/reference/Orientation/cI_NW.txt b/python/tests/reference/Orientation/cI_NW.txt index 754c69bba..b39889f28 100644 --- a/python/tests/reference/Orientation/cI_NW.txt +++ b/python/tests/reference/Orientation/cI_NW.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 225.41555594321144 83.13253115922213 83.08266205989301 1 1 134.58444405678856 83.13253115922211 6.917337940107012 1 2 diff --git a/python/tests/reference/Orientation/cI_Pitsch.txt b/python/tests/reference/Orientation/cI_Pitsch.txt index ef28bbb4d..6e0efddc6 100644 --- a/python/tests/reference/Orientation/cI_Pitsch.txt +++ b/python/tests/reference/Orientation/cI_Pitsch.txt @@ -1,4 +1,3 @@ -1 header 1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos 6.9173379401070045 83.13253115922213 44.58444405678856 1 1 45.0 89.99999999999999 279.7356103172453 1 2 diff --git a/python/tests/test_Table.py b/python/tests/test_Table.py index 8f617aff5..8afd6019e 100644 --- a/python/tests/test_Table.py +++ b/python/tests/test_Table.py @@ -60,13 +60,6 @@ class TestTable: new = Table.load(f) assert all(default.data==new.data) and default.shapes == new.shapes - def test_write_read_legacy_style(self,default,tmp_path): - with open(tmp_path/'legacy.txt','w') as f: - default.save(f,legacy=True) - with open(tmp_path/'legacy.txt') as f: - new = Table.load(f) - assert all(default.data==new.data) and default.shapes == new.shapes - def test_write_invalid_format(self,default,tmp_path): with pytest.raises(TypeError): default.save(tmp_path/'shouldnotbethere.txt',format='invalid') From 6fffad03161f39da88461db1947e2f0f7423c24b Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 10:27:31 +0100 Subject: [PATCH 036/219] automatically create documentation --- .gitlab-ci.yml | 3 ++- LICENSE | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 91f03c6af..62acc4b9c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -241,7 +241,8 @@ source_distribution: library_documentation: stage: deploy script: - - echo 'tbd one matesting1' + - cd $DAMASKROOT/PRIVATE/documenting/sphinx + - make html except: - master - release diff --git a/LICENSE b/LICENSE index 4290d15bd..0aaac06e9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2011-21 Max-Planck-Institut für Eisenforschung GmbH +Copyright 2011-2021 Max-Planck-Institut für Eisenforschung GmbH DAMASK is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From 0d3a1b120cab6d827e7b6e08c53c858b41fe9fb3 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 10:55:22 +0100 Subject: [PATCH 037/219] fail with error for test coverage below 90% currently, 94% of the statements in the python library are tested --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 62acc4b9c..c322b57d8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -96,7 +96,8 @@ processing: stage: python script: - cd $DAMASKROOT/python - - pytest --basetemp=${TESTROOT}/python -v + - pytest --basetemp=${TESTROOT}/python -v --cov --cov-report=term + - coverage report --fail-under=90 except: - master - release @@ -108,7 +109,6 @@ preprocessing_deprecated: except: - master - release - - release ################################################################################################### compile_grid_Intel: From 00d1c7151873bd3685b90474188fddb596ca9dec Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 10:57:34 +0100 Subject: [PATCH 038/219] J2 test with new table style --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index 888d95604..2a644d296 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 888d956040237bb9677e46863ac38604160b0234 +Subproject commit 2a644d296c16c145fccba548ea30a5e30409a783 From c742f7c9d09dbe968a851dcf2d133c6623b83e28 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 12:47:58 +0100 Subject: [PATCH 039/219] need to cope with _asciitable.py and _test.py --- .gitlab-ci.yml | 2 +- python/.coveragerc | 4 +--- python/damask/_grid.py | 15 ++++++--------- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c322b57d8..fafffead6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -97,7 +97,7 @@ processing: script: - cd $DAMASKROOT/python - pytest --basetemp=${TESTROOT}/python -v --cov --cov-report=term - - coverage report --fail-under=90 + - coverage report --fail-under=80 except: - master - release diff --git a/python/.coveragerc b/python/.coveragerc index 97114fb82..e15d64f56 100644 --- a/python/.coveragerc +++ b/python/.coveragerc @@ -1,4 +1,2 @@ [run] -omit = tests/* - damask/_asciitable.py - damask/_test.py +source = damask diff --git a/python/damask/_grid.py b/python/damask/_grid.py index 18c9b0d25..ed44989d7 100644 --- a/python/damask/_grid.py +++ b/python/damask/_grid.py @@ -270,12 +270,10 @@ class Grid: """ Load DREAM.3D (HDF5) file. - Data in DREAM.3D files can be stored per cell ('CellData') - and/or per grain ('Grain Data'). Per default, cell-wise data - is assumed. + Data in DREAM.3D files can be stored per cell ('CellData') and/or + per grain ('Grain Data'). Per default, cell-wise data is assumed. - damask.ConfigMaterial.load_DREAM3D allows to get the - corresponding material definition. + damask.ConfigMaterial.load_DREAM3D gives the corresponding material definition. Parameters ---------- @@ -303,8 +301,8 @@ class Grid: """ - b = util.DREAM3D_base_group(fname) if base_group is None else base_group - c = util.DREAM3D_cell_data_group(fname) if cell_data is None else cell_data + b = util.DREAM3D_base_group(fname) if base_group is None else base_group + c = util.DREAM3D_cell_data_group(fname) if cell_data is None else cell_data f = h5py.File(fname, 'r') cells = f[os.path.join(b,'_SIMPL_GEOMETRY','DIMENSIONS')][()] @@ -908,8 +906,7 @@ class Grid: def tainted_neighborhood(stencil,trigger): me = stencil[stencil.shape[0]//2] - return np.any(stencil != me - if len(trigger) == 0 else + return np.any(stencil != me if len(trigger) == 0 else np.in1d(stencil,np.array(list(set(trigger) - {me})))) offset_ = np.nanmax(self.material)+1 if offset is None else offset From 8a99306aedadac7619564261aafb29b8ddc6d41c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 14:34:18 +0100 Subject: [PATCH 040/219] old table not needed anymore --- python/damask/__init__.py | 1 - python/damask/_asciitable.py | 422 ----------------------------------- 2 files changed, 423 deletions(-) delete mode 100644 python/damask/_asciitable.py diff --git a/python/damask/__init__.py b/python/damask/__init__.py index a421e29c4..af9933954 100644 --- a/python/damask/__init__.py +++ b/python/damask/__init__.py @@ -34,5 +34,4 @@ from ._grid import Grid # noqa from ._result import Result # noqa # deprecated -from ._asciitable import ASCIItable # noqa from ._test import Test # noqa diff --git a/python/damask/_asciitable.py b/python/damask/_asciitable.py deleted file mode 100644 index 9d762369a..000000000 --- a/python/damask/_asciitable.py +++ /dev/null @@ -1,422 +0,0 @@ -import os -import sys -import re -import shlex -from collections.abc import Iterable - -import numpy as np - -# ------------------------------------------------------------------ -class ASCIItable(): - """Read and write to ASCII tables.""" - - tmpext = '_tmp' # filename extension for in-place access - -# ------------------------------------------------------------------ - def __init__(self, - name, - labeled = True, # assume table has labels - readonly = False, # no reading from file - ): - """Read and write to ASCII tables.""" - self.__IO__ = {'output': [], - 'labeled': labeled, # header contains labels - 'tags': [], # labels according to file info - 'dataStart': 0, - } - - self.__IO__['inPlace'] = name and not readonly - outname = name + self.tmpext if self.__IO__['inPlace'] else None # transparently create tmp file - - try: - self.__IO__['in'] = (open( name,'r') if os.access( name, os.R_OK) else None) if name else sys.stdin - except TypeError: - self.__IO__['in'] = name - - try: - self.__IO__['out'] = (open(outname,'w') if (not os.path.isfile(outname) or - os.access( outname, os.W_OK) - ) and - (not self.__IO__['inPlace'] or - not os.path.isfile(name) or - os.access( name, os.W_OK) - ) else None) if outname else sys.stdout - except TypeError: - self.__IO__['out'] = outname - - self.info = [] - self.tags = [] - self.data = [] - self.line = '' - - if self.__IO__['in'] is None \ - or self.__IO__['out'] is None: raise IOError # complain if any required file access not possible - - -# ------------------------------------------------------------------ - def _removeCRLF(self, - string): - """Delete any carriage return and line feed from string.""" - try: - return string.replace('\n','').replace('\r','') - except AttributeError: - return str(string) - -# ------------------------------------------------------------------ - def _quote(self, - what): - """Quote empty or white space-containing output.""" - return '{quote}{content}{quote}'.format( - quote = ('"' if str(what)=='' or re.search(r"\s",str(what)) else ''), - content = what) - -# ------------------------------------------------------------------ - def close(self, - dismiss = False): - if self.__IO__['in'] != sys.stdin: self.__IO__['in'].close() - self.output_flush() - if self.__IO__['out'] != sys.stdout: self.__IO__['out'].close() - if dismiss and os.path.isfile(self.__IO__['out'].name): - os.remove(self.__IO__['out'].name) - elif self.__IO__['inPlace']: - os.rename(self.__IO__['out'].name, self.__IO__['out'].name[:-len(self.tmpext)]) - -# ------------------------------------------------------------------ - def output_write(self, - what): - """Aggregate a single row (string) or list of (possibly containing further lists of) rows into output.""" - if isinstance(what, str): - self.__IO__['output'] += [what] - else: - try: - for item in what: self.output_write(item) - except TypeError: - self.__IO__['output'] += [str(what)] - - return self.output_flush() - -# ------------------------------------------------------------------ - def output_flush(self, - clear = True): - try: - self.__IO__['output'] == [] or self.__IO__['out'].write('\n'.join(self.__IO__['output']) + '\n') - except IOError: - return False - if clear: self.__IO__['output'] = [] - return True - -# ------------------------------------------------------------------ - def head_read(self): - """ - Get column labels. - - by either reading the first row or, - if keyword "head[*]" is present, the last line of the header - """ - try: - self.__IO__['in'].seek(0) - except IOError: - pass - - firstline = self.__IO__['in'].readline().strip() - m = re.search(r'(\d+)\s+head', firstline.lower()) # search for "head" keyword - - if m: # proper ASCIItable format - - if self.__IO__['labeled']: # table features labels - - self.info = [self.__IO__['in'].readline().strip() for i in range(1,int(m.group(1)))] - self.tags = shlex.split(self.__IO__['in'].readline()) # store tags found in last line - - else: - - self.info = [self.__IO__['in'].readline().strip() for i in range(0,int(m.group(1)))] # all header is info ... - - else: # other table format - self.__IO__['in'].seek(0) - - while self.data_read(advance = False, respectLabels = False): - if self.line[0] in ['#','!','%','/','|','*','$']: # "typical" comment indicators - self.info_append(self.line) # store comment as info - self.data_read() # wind forward one line - else: break # last line of comments - - if self.__IO__['labeled']: # table features labels - self.tags = self.data # get tags from last line in "header"... - self.data_read() # ...and remove from buffer - - if self.__IO__['labeled']: # table features tags - self.__IO__['tags'] = list(self.tags) # backup tags (make COPY, not link) - - try: - self.__IO__['dataStart'] = self.__IO__['in'].tell() # current file position is at start of data - except IOError: - pass - -# ------------------------------------------------------------------ - def head_write(self, - header = True): - """Write current header information (info + labels).""" - head = [f"{len(self.info)+self.__IO__['labeled']}\theader"] if header else [] - head.append(self.info) - if self.__IO__['labeled']: - head.append('\t'.join(map(self._quote,self.tags))) - if len(self.tags) == 0: raise ValueError('no labels present.') - - return self.output_write(head) - -# ------------------------------------------------------------------ - def labels_append(self, - what, - reset = False): - """Add item or list to existing set of labels (and switch on labeling).""" - if isinstance(what, str): - self.tags += [self._removeCRLF(what)] - else: - try: - for item in what: self.labels_append(item) - except TypeError: - self.tags += [self._removeCRLF(str(what))] - - self.__IO__['labeled'] = True # switch on processing (in particular writing) of tags - if reset: self.__IO__['tags'] = list(self.tags) # subsequent data_read uses current tags as data size - -# ------------------------------------------------------------------ - def labels_clear(self): - """Delete existing labels and switch to no labeling.""" - self.tags = [] - self.__IO__['labeled'] = False - -# ------------------------------------------------------------------ - def labels(self, - tags = None, - raw = False): - """ - Tell abstract labels. - - "x" for "1_x","2_x",... unless raw output is requested. - operates on object tags or given list. - """ - if tags is None: tags = self.tags - - if isinstance(tags, Iterable) and not raw: # check whether list of tags is requested - id = 0 - dim = 1 - labelList = [] - - while id < len(tags): - if not tags[id].startswith('1_'): - labelList.append(tags[id]) - else: - label = tags[id][2:] # get label - while id < len(tags) and tags[id] == f'{dim}_{label}': # check successors - id += 1 # next label... - dim += 1 # ...should be one higher dimension - labelList.append(label) # reached end --> store - id -= 1 # rewind one to consider again - - id += 1 - dim = 1 - - else: - labelList = self.tags - - return labelList - -# ------------------------------------------------------------------ - def label_index(self, - labels): - """ - Tell index of column label(s). - - return numpy array if asked for list of labels. - transparently deals with label positions implicitly given as numbers or their headings given as strings. - """ - if isinstance(labels, Iterable) and not isinstance(labels, str): # check whether list of labels is requested - idx = [] - for label in labels: - if label is not None: - try: - idx.append(int(label)-1) # column given as integer number? - except ValueError: - label = label[1:-1] if label[0] == label[-1] and label[0] in ('"',"'") else label # remove outermost quotations - try: - idx.append(self.tags.index(label)) # locate string in label list - except ValueError: - try: - idx.append(self.tags.index('1_'+label)) # locate '1_'+string in label list - except ValueError: - idx.append(-1) # not found... - else: - try: - idx = int(labels)-1 # offset for python array indexing - except ValueError: - try: - labels = labels[1:-1] if labels[0] == labels[-1] and labels[0] in ('"',"'") else labels # remove outermost quotations - idx = self.tags.index(labels) - except ValueError: - try: - idx = self.tags.index('1_'+labels) # locate '1_'+string in label list - except ValueError: - idx = None if labels is None else -1 - - return np.array(idx) if isinstance(idx,Iterable) else idx - -# ------------------------------------------------------------------ - def label_dimension(self, - labels): - """ - Tell dimension (length) of column label(s). - - return numpy array if asked for list of labels. - transparently deals with label positions implicitly given as numbers or their headings given as strings. - """ - listOfLabels = isinstance(labels, Iterable) and not isinstance(labels, str) # check whether list of labels is requested - if not listOfLabels: labels = [labels] - - dim = [] - for label in labels: - if label is not None: - myDim = -1 - try: # column given as number? - idx = int(label)-1 - myDim = 1 # if found treat as single column of dimension 1 - except ValueError: # column has string label - label = label[1:-1] if label[0] == label[-1] and label[0] in ('"',"'") else label # remove outermost quotations - if label in self.tags: # can be directly found? - myDim = 1 # scalar by definition - elif '1_'+label in self.tags: # look for first entry of possible multidim object - idx = self.tags.index('1_'+label) # get starting column - myDim = 1 # (at least) one-dimensional - while idx+myDim < len(self.tags) and self.tags[idx+myDim].startswith("%i_"%(myDim+1)): - myDim += 1 # keep adding while going through object - - dim.append(myDim) - - return np.array(dim) if listOfLabels else dim[0] - -# ------------------------------------------------------------------ - def label_indexrange(self, - labels): - """ - Tell index range for given label(s). - - return numpy array if asked for list of labels. - transparently deals with label positions implicitly given as numbers or their headings given as strings. - """ - start = self.label_index(labels) - dim = self.label_dimension(labels) - - return np.hstack([range(s,s+d) for s,d in zip(start,dim)]).astype(int) \ - if isinstance(labels, Iterable) and not isinstance(labels, str) \ - else range(start,start+dim) - -# ------------------------------------------------------------------ - def info_append(self, - what): - """Add item or list to existing set of infos.""" - if isinstance(what, str): - self.info += [self._removeCRLF(what)] - else: - try: - for item in what: self.info_append(item) - except TypeError: - self.info += [self._removeCRLF(str(what))] - -# ------------------------------------------------------------------ - def info_clear(self): - """Delete any info block.""" - self.info = [] - -# ------------------------------------------------------------------ - def data_rewind(self): - self.__IO__['in'].seek(self.__IO__['dataStart']) # position file to start of data section - self.tags = list(self.__IO__['tags']) # restore label info found in header (as COPY, not link) - self.__IO__['labeled'] = len(self.tags) > 0 - -# ------------------------------------------------------------------ - def data_read(self, - advance = True, - respectLabels = True): - """Read next line and parse it into data array.""" - self.line = self.__IO__['in'].readline().strip() - - self.line = self.line.rstrip('\n') - - if self.__IO__['labeled'] and respectLabels: # if table has labels - items = shlex.split(self.line)[:len(self.__IO__['tags'])] # use up to label count (from original file info) - self.data = items if len(items) == len(self.__IO__['tags']) else [] # take entries if label count matches - else: - self.data = shlex.split(self.line) # otherwise take all - - return self.data != [] - -# ------------------------------------------------------------------ - def data_readArray(self, - labels = []): - """Read whole data of all (given) labels as numpy array.""" - try: - self.data_rewind() # try to wind back to start of data - except IOError: - pass # assume/hope we are at data start already... - - if labels is None or labels == []: - use = None # use all columns (and keep labels intact) - labels_missing = [] - else: - if isinstance(labels, str) or not isinstance(labels, Iterable): # check whether labels are a list or single item - labels = [labels] - indices = self.label_index(labels) # check requested labels ... - dimensions = self.label_dimension(labels) # ... and remember their dimension - present = np.where(indices >= 0)[0] # positions in request list of labels that are present ... - missing = np.where(indices < 0)[0] # ... and missing in table - labels_missing = np.array(labels)[missing] # labels of missing data - - columns = [] - for i,(c,d) in enumerate(zip(indices[present],dimensions[present])): # for all valid labels ... - # ... transparently add all components unless column referenced by number or with explicit dimension - columns += list(range(c,c + - (d if str(c) != str(labels[present[i]]) else - 1))) - use = np.array(columns) if len(columns) > 0 else None - - self.tags = list(np.array(self.__IO__['tags'])[use]) # update labels with valid subset - - self.data = np.loadtxt(self.__IO__['in'],usecols=use,ndmin=2) - - return labels_missing - -# ------------------------------------------------------------------ - def data_write(self): - """Write current data array and report alive output back.""" - if len(self.data) == 0: return True - - if isinstance(self.data[0],list): - return self.output_write(['\t'.join(map(self._quote,items)) for items in self.data]) - else: - return self.output_write( '\t'.join(map(self._quote,self.data))) - -# ------------------------------------------------------------------ - def data_writeArray(self): - """Write whole numpy array data.""" - for row in self.data: - try: - output = list(map(repr,row)) - except Exception: - output = [repr(row)] - - try: - self.__IO__['out'].write('\t'.join(output) + '\n') - except Exception: - pass - -# ------------------------------------------------------------------ - def data_append(self, - what): - if isinstance(what, str): - self.data += [what] - else: - try: - for item in what: self.data_append(item) - except TypeError: - self.data += [str(what)] From 69e851fd3136ad974766161aff80a2f28a4fdf6e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 14:35:30 +0100 Subject: [PATCH 041/219] includes fixed J2 test --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index 2a644d296..73e9cdff9 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 2a644d296c16c145fccba548ea30a5e30409a783 +Subproject commit 73e9cdff9fb2e056e48c1f09b4456db48d04669f From cc72fad86a22712e0639d9057b97b9cb9ae0225f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 15:12:29 +0100 Subject: [PATCH 042/219] split configuration per physics --- PRIVATE | 2 +- .../mechanical/plastic/phenopowerlaw_Au.yaml} | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) rename examples/config/{Phase_Phenopowerlaw_Gold.yaml => phase/mechanical/plastic/phenopowerlaw_Au.yaml} (82%) diff --git a/PRIVATE b/PRIVATE index 73e9cdff9..1e305f8bc 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 73e9cdff9fb2e056e48c1f09b4456db48d04669f +Subproject commit 1e305f8bc3cbae5e412d1ac99a7a2675d1725120 diff --git a/examples/config/Phase_Phenopowerlaw_Gold.yaml b/examples/config/phase/mechanical/plastic/phenopowerlaw_Au.yaml similarity index 82% rename from examples/config/Phase_Phenopowerlaw_Gold.yaml rename to examples/config/phase/mechanical/plastic/phenopowerlaw_Au.yaml index 4dbed9ce2..4fc233ce5 100644 --- a/examples/config/Phase_Phenopowerlaw_Gold.yaml +++ b/examples/config/phase/mechanical/plastic/phenopowerlaw_Au.yaml @@ -2,12 +2,9 @@ # On the mathematical description of the tensile stress-strain curves of polycrystalline face centered cubic metals # International Journal of Plasticity, Volume 12, Issue 1, 1996, Pages 35-43 # DOI: 10.1016/S0749-6419(95)00043-7 - -Gold: +Au: lattice: cF mechanical: - output: [F, P, F_e, F_p, L_p, O] - elastic: {type: hooke, C_11: 191e9, C_12: 162e9, C_44: 42.2e9} plastic: type: phenopowerlaw output: [xi_sl] From 480b8315a722185b5bce98aa4d923e0404d0edf7 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 15:54:29 +0100 Subject: [PATCH 043/219] cleaning + testing --- .gitlab-ci.yml | 2 +- PRIVATE | 2 +- examples/config/Phase_None_Orthorhombic.config | 15 --------------- .../Homogenization_None_Dummy.config | 3 --- python/damask/_rotation.py | 2 +- 5 files changed, 3 insertions(+), 21 deletions(-) delete mode 100644 examples/config/Phase_None_Orthorhombic.config delete mode 100644 examples/config/homogenization/Homogenization_None_Dummy.config diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fafffead6..71d181977 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -97,7 +97,7 @@ processing: script: - cd $DAMASKROOT/python - pytest --basetemp=${TESTROOT}/python -v --cov --cov-report=term - - coverage report --fail-under=80 + - coverage report --fail-under=85 except: - master - release diff --git a/PRIVATE b/PRIVATE index 1e305f8bc..978d132e3 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 1e305f8bc3cbae5e412d1ac99a7a2675d1725120 +Subproject commit 978d132e3baaf60e00f8ac2e70f00285c5cc0328 diff --git a/examples/config/Phase_None_Orthorhombic.config b/examples/config/Phase_None_Orthorhombic.config deleted file mode 100644 index d7955cf2a..000000000 --- a/examples/config/Phase_None_Orthorhombic.config +++ /dev/null @@ -1,15 +0,0 @@ -[Orthorombic] - -elasticity hooke -plasticity none - -lattice_structure orthorhombic -c11 106.75e9 -c22 106.75e9 -c33 106.75e9 -c12 60.41e9 -c13 60.41e9 -c23 60.41e9 -c44 28.34e9 -c55 28.34e9 -c66 28.34e9 diff --git a/examples/config/homogenization/Homogenization_None_Dummy.config b/examples/config/homogenization/Homogenization_None_Dummy.config deleted file mode 100644 index fc608c6c4..000000000 --- a/examples/config/homogenization/Homogenization_None_Dummy.config +++ /dev/null @@ -1,3 +0,0 @@ -[directSX] -mech none - diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 8d8a13d99..ec231348b 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -71,7 +71,7 @@ class Rotation: def __repr__(self): """Represent rotation as unit quaternion(s).""" - return f'Quaternion{" " if self.quaternion.shape == (4,) else "s of shape "+str(self.quaternion.shape)+chr(10)}'\ + return f'Quaternion{" " if self.quaternion.shape == (4,) else "s of shape "+str(self.quaternion.shape[:-1])+chr(10)}'\ + str(self.quaternion) From 26e63286643f3cc07393d18ffe9141589f79aead Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 16:28:47 +0100 Subject: [PATCH 044/219] important things first --- examples/grid/material.yaml | 38 +++---- examples/mesh/material.yaml | 206 ++++++++++++++++++------------------ 2 files changed, 122 insertions(+), 122 deletions(-) diff --git a/examples/grid/material.yaml b/examples/grid/material.yaml index 0a3f83858..b499e7413 100644 --- a/examples/grid/material.yaml +++ b/examples/grid/material.yaml @@ -4,6 +4,25 @@ homogenization: N_constituents: 1 mechanical: {type: pass} +phase: + Aluminum: + lattice: cF + mechanical: + output: [F, P, F_e, F_p, L_p, O] + elastic: {type: Hooke, C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9} + plastic: + type: phenopowerlaw + N_sl: [12] + a_sl: 2.25 + atol_xi: 1.0 + dot_gamma_0_sl: 0.001 + h_0_sl_sl: 75e6 + h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4] + n_sl: 20 + output: [xi_sl] + xi_0_sl: [31e6] + xi_inf_sl: [63e6] + material: - homogenization: SX constituents: @@ -105,22 +124,3 @@ material: - phase: Aluminum v: 1.0 O: [0.7729330445886478, 0.21682179052722322, -0.5207379472917645, 0.2905078484066341] - -phase: - Aluminum: - lattice: cF - mechanical: - output: [F, P, F_e, F_p, L_p, O] - elastic: {C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9, type: hooke} - plastic: - N_sl: [12] - a_sl: 2.25 - atol_xi: 1.0 - dot_gamma_0_sl: 0.001 - h_0_sl_sl: 75e6 - h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4] - n_sl: 20 - output: [xi_sl] - type: phenopowerlaw - xi_0_sl: [31e6] - xi_inf_sl: [63e6] diff --git a/examples/mesh/material.yaml b/examples/mesh/material.yaml index 333073150..5a135bff1 100644 --- a/examples/mesh/material.yaml +++ b/examples/mesh/material.yaml @@ -1,15 +1,16 @@ homogenization: SX: N_constituents: 1 - mechanics: {type: none} + mechanics: {type: pass} phase: Aluminum: lattice: cF mechanics: output: [F, P, F_e, F_p, L_p] - elasticity: {C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9, type: hooke} + elasticity: {type: Hooke, C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9} plasticity: + type: phenopowerlaw N_sl: [12] a_sl: 2.25 atol_xi: 1.0 @@ -18,508 +19,507 @@ phase: h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4] n_sl: 20 output: [xi_sl] - type: phenopowerlaw xi_0_sl: [31e6] xi_inf_sl: [63e6] material: - constituents: - O: [0.12807292351503236, 0.22200469518411023, 0.6352813278477609, -0.7285114110750144] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.372279509887385, 0.7538147166654958, 0.5325170025119552, -0.09796418474222598] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.36250483607280015, 0.1909385526545633, 0.22801354774620894, 0.883256777487838] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.732294920525089, 0.5171063011556195, -0.1407961220188403, 0.4201448258669421] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.708826030342622, -0.6702053835750753, -0.20103371291967786, -0.08930760776907508] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.5987257793404215, -0.07651654961032513, 0.5682302685884709, 0.5592736545277363] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.06694940093926707, -0.30782756132267486, -0.12043616569331547, 0.9414112279960869] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.18461382116884548, -0.6204161624733774, -0.29958251820830917, 0.700893599028564] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.9169840196863235, -0.06434514294945529, -0.39316017660689456, -0.02061760774585527] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.6721337568887824, 0.25328061978301336, 0.695177984796291, 0.028508068111876502] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.5634397986285561, 0.5706880594373327, 0.08060455928790704, 0.5919067808017289] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.5400408176755693, -0.4956697116684921, 0.14064883310776702, 0.6654963245008945] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.07812412485408982, 0.5540083408137547, 0.5031719732018802, -0.6586268631089227] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.41240828720357114, -0.026821321952330345, -0.06656740215323173, -0.9081678271691396] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.3658567189933218, -0.6119251240676276, 0.3102501533620181, -0.6288412725331445] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.2308179184918794, 0.26432722557112004, -0.14038019870347257, -0.925822664518926] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.4363489638426341, -0.5213523479018052, -0.37065469878209856, -0.6327767421148525] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.15751083378097516, -0.5830676086424881, -0.7731435878587035, -0.19357554997086668] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.41698573506483805, 0.5882742372124636, 0.4716906164392004, 0.5075079122021035] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.17835925061073415, -0.7576341567357145, 0.5458453874401553, 0.3102116620619653] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.016537212068790805, -0.06560032016255024, -0.9814007903497085, 0.17965413246716677] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.7933419088044938, -0.4975616690562898, 0.002907610903989995, 0.35075995640778657] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.3635770516878745, -0.09660008514915623, 0.36238757501055235, 0.8527340713921895] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.35469467802378446, 0.900798059498047, 0.14285057027288334, -0.20578691882349764] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.06696575255653868, 0.5321303636902097, -0.6166115894646206, 0.5763184985417141] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.31809816235976984, 0.4876502255202392, -0.7296452532806524, -0.3586483249903866] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.2549514949878876, 0.05524371396681128, 0.9470351218726387, -0.18727612023499066] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.3760153183052231, -0.4217640210815424, 0.6443784334217433, -0.515270827295598] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.6102174060370085, -0.022958466699548683, -0.6694455254088741, -0.42302519391438936] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.5254549417230717, 0.20193294294562072, -0.19303567281299983, -0.8036525491739303] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.7169626866664082, -0.6629494257626796, -0.1589260699014312, -0.14561960415653047] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.040377943142626056, 0.7396298011497441, -0.661651923110657, -0.11633620074048379] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.8080395996415211, -0.5263437715228787, 0.22303374382245625, -0.1424436334371638] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.21962598047172166, 0.45293590819075397, -0.06718005388282963, -0.8614524549466163] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.7348220818417669, 0.06949262003518837, 0.20336956395879577, 0.643310270595446] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.27437168454785316, 0.607839586873941, -0.06548653269996256, -0.7422686369382898] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.5821287086059501, 0.5669682803260325, -0.47414005369298196, 0.338916428054065] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.3970593041780103, 0.8246645098423279, -0.36199337531483944, 0.1767290338352959] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.5081480477127669, 0.3204901365034085, 0.7369345512733142, -0.3098372171791651] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.6953483497932282, -0.7005111230189092, -0.030120917781595695, -0.15769454422590312] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.20780780106593144, -0.4156481640905742, -0.859796494212616, -0.2116660342236624] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.875449475108018, 0.334405906289409, 0.08321243768586052, 0.3388754883231179] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.4878954087431437, -0.201899911445109, -0.016443700876142255, 0.8490724943061776] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.809006993377334, -0.4511704605616954, 0.3107581234699541, 0.21303119227133527] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.2783061701232137, -0.37155930333092624, 0.2983006011383234, 0.833970090075238] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.8685487200401724, 0.4286175969913296, 0.2073677875225473, -0.13750882576751258] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.8559566148691011, 0.23856401969856064, 0.39423286552950637, 0.23453342982075753] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.1756511736975092, 0.07342062889304078, -0.04772989392115008, -0.9805498119207986] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.7200508938250222, 0.6735134759580867, -0.1233849919850085, 0.11261639204619212] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.047335400154722915, 0.49129103138311975, 0.525630527898618, -0.6928961181271857] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.28118642835330543, 0.5395929890335265, 0.40425497687514045, 0.6828993427786086] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.006026285215314257, -0.1679148292265234, -0.7479485565815042, -0.6421380308936511] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.334648430137024, 0.6496056109679386, -0.1394793624167455, 0.6682577989560725] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.7232075581792949, -0.28960085183792955, -0.6223046032924913, -0.07641436467093393] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.47299579296952254, -0.5670338162851795, -0.5015824290282452, 0.45073572957146774] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.5759837103124865, 0.47483366659316206, 0.13338249877309968, -0.6519086312861638] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.2133016608721166, 0.8062208250934307, -0.14645674169152062, 0.5320345904807013] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.7863833344402563, 0.15848713668741257, 0.5963350020823727, 0.02945579927053303] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.2759341654421687, -0.6656009677995011, 0.632033964698132, -0.2852520910949854] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.3400173283191303, 0.2790322396525497, 0.05686903943434476, -0.8962673362513095] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.3090337373688507, -0.6179184060817985, -0.40306280271429823, -0.6001794478831014] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.48435626950922916, 0.11609254154182697, 0.8072509012091782, 0.31665045157465316] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.9341912300459765, 0.06381865157465592, -0.2688666295423878, 0.22566493067132626] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.3246762949389304, -0.8214600528123802, 0.1647217509197912, -0.43892531245318767] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.22010536155962523, 0.3952675899243737, -0.4188983380967744, 0.787300034616946] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.4751050223053463, -0.4218758221556333, 0.4821369300658099, -0.6031915028641082] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.880861720439117, 0.09303992127699898, 0.06428592081503388, 0.459666752004941] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.017063839192766467, -0.6261860403002049, 0.7746195154331581, 0.0869739882680612] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.8252329561137333, 0.43850926617938535, -0.16721886267130043, 0.314226102648273] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.4088699582548411, 0.5235534931618994, 0.2277666883750278, -0.7119265641211392] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.31369184472576933, -0.5429805343259477, -0.5533576236189442, -0.5482380014906362] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.8207922579932034, -0.40913772106857016, -0.29054259084664685, 0.2729311219362013] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.39996686955088523, 0.8073277952554248, -0.42163315248684, 0.10234167769627939] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.14522555946678525, -0.9642883914638805, -0.07079650136982708, -0.20986969852590256] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.8609444342657742, -0.4171158046302133, 0.08690127066297638, -0.2779159149664443] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.09931399908465133, 0.16026167862873547, -0.3511391996430844, 0.9171445831617433] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.6587918595877198, 0.6189906598816806, 0.0005033162297445391, 0.42760214615103187] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.7412785017238798, -0.6379030203895805, -0.20813887288112973, -0.016252047736315157] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.5032998395625615, -0.8189944544199759, -0.2752734056777696, 0.012724278061564797] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.30815895127983317, 0.20282878988385175, 0.8579906660791383, -0.3574221029279561] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.0912817179686122, 0.5543695707221443, -0.21745503821012058, 0.7981574615193918] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.718183481882936, 0.6611923783626078, 0.21674094418893908, 0.007777419738431369] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.641563954107516, 0.47603559168775506, 0.3154268571613459, 0.512144223844938] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.8439024683820513, 0.43153248029761754, -0.2652577072450959, -0.1767673359360896] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.17482457972766288, 0.13632980653604765, -0.729153335123429, -0.6474457228612067] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.5462682331321344, -0.6419412420912892, 0.5193526292629735, -0.14062469786856494] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.06193959356412827, 0.9446609987066811, 0.2955015499517284, 0.12828841821354212] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.13005379758833394, -0.4761566918831448, -0.8677539374042601, -0.0579992985057245] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.12401013449245081, -0.9269166108137696, 0.1869992698940139, -0.30079620376558064] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.6368058430024911, 0.28319472159332215, 0.09883070908659818, -0.7102897710941695] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.7479222172438762, 0.5613955239110566, -0.3036337525818155, -0.18235670258786588] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.13628779568798424, -0.7300975764648174, 0.27927071064003745, -0.6085975975678171] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.24072388217536397, -0.41900940030067935, -0.16600482052691715, 0.859607779497087] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.75515292090621, 0.08155675624188279, -0.050775397210192544, 0.6484708324946223] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.6714109994800408, 0.44985122714627734, -0.39700997413825245, -0.4349991076392517] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.42120801893902454, -0.5534446724220495, -0.5021395923844388, 0.5139441887103136] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.021268573686443606, 0.024774237164421335, -0.3057203971540149, -0.9515613084348569] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.7264452778402825, -0.06307246428220294, -0.667017211813705, -0.15292861634499988] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.23746818259636918, 0.6362552151914914, 0.7106717442450251, -0.18366773077418935] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX - constituents: - O: [0.24869738401636882, 0.6772930680861174, -0.5511240766607762, 0.4191490942740014] - fraction: 1.0 + v: 1.0 phase: Aluminum homogenization: SX From 7072ab0984dcca6cac45731376c9a77088de756a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 17:07:36 +0100 Subject: [PATCH 045/219] non-converging simulation is an error --- src/IO.f90 | 12 ++---------- src/grid/DAMASK_grid.f90 | 3 +-- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/IO.f90 b/src/IO.f90 index 36b774191..0ed26b1d4 100644 --- a/src/IO.f90 +++ b/src/IO.f90 @@ -524,16 +524,8 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg) msg = 'mixed boundary conditions allow rotation' case (839) msg = 'non-positive restart frequency in grid load case' - case (841) - msg = 'missing header length info in grid mesh' - case (842) - msg = 'incomplete information in grid mesh header' - case (843) - msg = 'material count mismatch' case (844) msg = 'invalid VTR file' - case (846) - msg = 'rotation for load case rotation ill-defined (R:RT != I)' case (891) msg = 'unknown solver type selected' case (892) @@ -541,6 +533,8 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg) case (894) msg = 'MPI error' + case (950) + msg = 'max number of cut back exceeded, terminating' !------------------------------------------------------------------------------------------------- ! general error messages @@ -606,8 +600,6 @@ subroutine IO_warning(warning_ID,el,ip,g,ext_msg) msg = 'unknown crystal symmetry' case (709) msg = 'read only the first document' - case (850) - msg = 'max number of cut back exceeded, terminating' case default msg = 'unknown warning number' end select diff --git a/src/grid/DAMASK_grid.f90 b/src/grid/DAMASK_grid.f90 index abf86e161..7bbb71872 100644 --- a/src/grid/DAMASK_grid.f90 +++ b/src/grid/DAMASK_grid.f90 @@ -441,9 +441,8 @@ program DAMASK_grid timeinc = timeinc/real(subStepFactor,pReal) ! cut timestep print'(/,a)', ' cutting back ' else ! no more options to continue - call IO_warning(850) if (worldrank == 0) close(statUnit) - call quit(0) + call IO_error(950) endif enddo subStepLooping From ee3d3b75c7c608cbefd87cf17d52294343815d4c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 17:10:50 +0100 Subject: [PATCH 046/219] thermal examples + tests --- PRIVATE | 2 +- .../config/phase/thermal/externalheat_adiabatic.yaml | 11 +++++++++++ .../phase/thermal/externalheat_fast-convection.yaml | 11 +++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 examples/config/phase/thermal/externalheat_adiabatic.yaml create mode 100644 examples/config/phase/thermal/externalheat_fast-convection.yaml diff --git a/PRIVATE b/PRIVATE index 978d132e3..1df86eb3d 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 978d132e3baaf60e00f8ac2e70f00285c5cc0328 +Subproject commit 1df86eb3d63923557406999ed5a1b41a27fb1fda diff --git a/examples/config/phase/thermal/externalheat_adiabatic.yaml b/examples/config/phase/thermal/externalheat_adiabatic.yaml new file mode 100644 index 000000000..e34f4fc5b --- /dev/null +++ b/examples/config/phase/thermal/externalheat_adiabatic.yaml @@ -0,0 +1,11 @@ +adiabatic: + rho: 1 + thermal: + c_p: 1 + K_11: 0 + K_22: 0 + K_33: 0 + source: + - type: externalheat + f_T: [1, 1, 0, 0] + t_n: [0, 500, 500.001, 1000] diff --git a/examples/config/phase/thermal/externalheat_fast-convection.yaml b/examples/config/phase/thermal/externalheat_fast-convection.yaml new file mode 100644 index 000000000..c7f2df61b --- /dev/null +++ b/examples/config/phase/thermal/externalheat_fast-convection.yaml @@ -0,0 +1,11 @@ +fast-convection: + rho: 1 + thermal: + c_p: 1 + K_11: 1e30 + K_22: 1e30 + K_33: 1e30 + source: + - type: externalheat + f_T: [1, 1, 0, 0] + t_n: [0, 500, 500.001, 1000] From 20c95491980fd067f9be8e135986d7f1f2ac33e2 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 18:00:13 +0100 Subject: [PATCH 047/219] polishing thread sanitizer throws warnings, probably because off 'terminallyIll' --- cmake/Compiler-GNU.cmake | 6 ++++-- src/phase_mechanical_plastic_nonlocal.f90 | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cmake/Compiler-GNU.cmake b/cmake/Compiler-GNU.cmake index 1089e73f1..b9a7406dc 100644 --- a/cmake/Compiler-GNU.cmake +++ b/cmake/Compiler-GNU.cmake @@ -131,8 +131,10 @@ set (DEBUG_FLAGS "${DEBUG_FLAGS} -fcheck=all") set (DEBUG_FLAGS "${DEBUG_FLAGS} -fstack-protector-all") # Inserts a guard variable onto the stack frame for all functions -# Detect memory leaks -# -fsanitize=address +set (DEBUG_FLAGS "${DEBUG_FLAGS} -fsanitize=undefined") +# detect undefined behavior +# Additional options +# -fsanitize=address,leak,thread #------------------------------------------------------------------------------------------------ # precision settings diff --git a/src/phase_mechanical_plastic_nonlocal.f90 b/src/phase_mechanical_plastic_nonlocal.f90 index e4e008fab..2ceaea7e2 100644 --- a/src/phase_mechanical_plastic_nonlocal.f90 +++ b/src/phase_mechanical_plastic_nonlocal.f90 @@ -1819,7 +1819,7 @@ subroutine storeGeometry(ph) integer, intent(in) :: ph - integer :: ip, el, ce, co + integer :: ce, co real(pReal), dimension(:), allocatable :: V From 33b601461b58a1414e186c8baa07f84c2e6b469e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 18:47:53 +0100 Subject: [PATCH 048/219] modularizing further steepens the learning curve. But ensures that ther IS a learning curve --- PRIVATE | 2 +- examples/config/Phase_Thermal.config | 4 --- examples/config/phase/alpha-Ti.yaml | 2 ++ examples/config/phase/bcc.yaml | 1 + examples/config/phase/fcc.yaml | 1 + .../phase/mechanical/elastic/Hooke_Al.yaml | 20 ++++++--------- .../phase/mechanical/elastic/Hooke_Au.yaml | 20 ++++++--------- .../phase/mechanical/elastic/Hooke_Ni.yaml | 20 ++++++--------- .../phase/mechanical/elastic/Hooke_cpTi.yaml | 25 ++++++++----------- .../mechanical/plastic/phenopowerlaw_Au.yaml | 24 ++++++++---------- 10 files changed, 49 insertions(+), 70 deletions(-) delete mode 100644 examples/config/Phase_Thermal.config create mode 100644 examples/config/phase/alpha-Ti.yaml create mode 100644 examples/config/phase/bcc.yaml create mode 100644 examples/config/phase/fcc.yaml diff --git a/PRIVATE b/PRIVATE index 1df86eb3d..535310ae7 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 1df86eb3d63923557406999ed5a1b41a27fb1fda +Subproject commit 535310ae792895d1eca5d45af335cd7e227af145 diff --git a/examples/config/Phase_Thermal.config b/examples/config/Phase_Thermal.config deleted file mode 100644 index 9c8baafa9..000000000 --- a/examples/config/Phase_Thermal.config +++ /dev/null @@ -1,4 +0,0 @@ -thermal_conductivity11 237.0 -specific_heat 910.0 -mass_density 2700.0 -reference_temperature 300.0 diff --git a/examples/config/phase/alpha-Ti.yaml b/examples/config/phase/alpha-Ti.yaml new file mode 100644 index 000000000..5bd2580a2 --- /dev/null +++ b/examples/config/phase/alpha-Ti.yaml @@ -0,0 +1,2 @@ +lattice: hP +c/a: 1.587 diff --git a/examples/config/phase/bcc.yaml b/examples/config/phase/bcc.yaml new file mode 100644 index 000000000..bb7ef10df --- /dev/null +++ b/examples/config/phase/bcc.yaml @@ -0,0 +1 @@ +lattice: cI diff --git a/examples/config/phase/fcc.yaml b/examples/config/phase/fcc.yaml new file mode 100644 index 000000000..04f02509d --- /dev/null +++ b/examples/config/phase/fcc.yaml @@ -0,0 +1 @@ +lattice: cF diff --git a/examples/config/phase/mechanical/elastic/Hooke_Al.yaml b/examples/config/phase/mechanical/elastic/Hooke_Al.yaml index 583ad183d..025f1ca25 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Al.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Al.yaml @@ -1,12 +1,8 @@ -Al: - lattice: cF - mechanical: - elastic: - type: Hooke - references: - - J. Vallin et al., - Journal of Applied Physics 35(6), 1825-1826, 1964, - 10.1063/1.1713749 - C_11: 107.3e9 - C_12: 60.8e9 - C_44: 28.3e9 +type: Hooke +references: + - J. Vallin et al., + Journal of Applied Physics 35(6), 1825-1826, 1964, + 10.1063/1.1713749 +C_11: 107.3e9 +C_12: 60.8e9 +C_44: 28.3e9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Au.yaml b/examples/config/phase/mechanical/elastic/Hooke_Au.yaml index b2d6cde08..9a4da774d 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Au.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Au.yaml @@ -1,12 +1,8 @@ -Au: - lattice: cF - mechanical: - elastic: - type: Hooke - references: - - J.P. Hirth and J. Lothe, - Theory of Dislocations, 1982, - John Wiley & Sons - C_11: 186e9 - C_12: 157e9 - C_44: 42e9 +type: Hooke +references: + - J.P. Hirth and J. Lothe, + Theory of Dislocations, 1982, + John Wiley & Sons +C_11: 186e9 +C_12: 157e9 +C_44: 42e9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml b/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml index 0b032c350..c76632cdd 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml @@ -1,12 +1,8 @@ -Ni: - lattice: cF - mechanical: - elastic: - type: Hooke - references: - - J.P. Hirth and J. Lothe, - Theory of Dislocations, 1982, - John Wiley & Sons - C_11: 246.5e9 - C_12: 147.3e9 - C_44: 124.7e9 +type: Hooke +references: + - J.P. Hirth and J. Lothe, + Theory of Dislocations, 1982, + John Wiley & Sons +C_11: 246.5e9 +C_12: 147.3e9 +C_44: 124.7e9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml b/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml index a3ba24d6c..8684614a4 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_cpTi.yaml @@ -1,15 +1,10 @@ -cpTi: - lattice: hP - c/a: 1.587 - mechanical: - elastic: - type: Hooke - references: - - L. Wang et al., - Acta Materialia 132, 598-610, 2017, - 10.1016/j.actamat.2017.05.015 - C_11: 162.4e9 - C_33: 181.6e9 - C_44: 47.2e9 - C_12: 92e9 - C_13: 69e9 +type: Hooke +references: + - L. Wang et al., + Acta Materialia 132, 598-610, 2017, + 10.1016/j.actamat.2017.05.015 +C_11: 162.4e9 +C_33: 181.6e9 +C_44: 47.2e9 +C_12: 92e9 +C_13: 69e9 diff --git a/examples/config/phase/mechanical/plastic/phenopowerlaw_Au.yaml b/examples/config/phase/mechanical/plastic/phenopowerlaw_Au.yaml index 4fc233ce5..daaab878d 100644 --- a/examples/config/phase/mechanical/plastic/phenopowerlaw_Au.yaml +++ b/examples/config/phase/mechanical/plastic/phenopowerlaw_Au.yaml @@ -2,17 +2,13 @@ # On the mathematical description of the tensile stress-strain curves of polycrystalline face centered cubic metals # International Journal of Plasticity, Volume 12, Issue 1, 1996, Pages 35-43 # DOI: 10.1016/S0749-6419(95)00043-7 -Au: - lattice: cF - mechanical: - plastic: - type: phenopowerlaw - output: [xi_sl] - N_sl: [12] - n_sl: 83 - dot_gamma_0_sl: 0.001 - h_0_sl_sl: 75e6 - h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4] - a_sl: 1.0 - xi_0_sl: [26e6] - xi_inf_sl: [53e6] +type: phenopowerlaw +output: [xi_sl] +N_sl: [12] +n_sl: 83 +dot_gamma_0_sl: 0.001 +h_0_sl_sl: 75e6 +h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4] +a_sl: 1.0 +xi_0_sl: [26e6] +xi_inf_sl: [53e6] From 0072ebfa649b7d9ee6e4636ec12a9a4dec007db5 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 23:17:04 +0100 Subject: [PATCH 049/219] polishing --- src/grid/grid_mech_FEM.f90 | 12 +++++------- src/grid/grid_mech_spectral_basic.f90 | 6 ++---- src/grid/grid_mech_spectral_polarisation.f90 | 7 ++----- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index aa9e705a6..1ff356cb9 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -190,11 +190,11 @@ subroutine grid_mechanical_FEM_init CHKERRQ(ierr) call DMSNESSetJacobianLocal(mechanical_grid,formJacobian,PETSC_NULL_SNES,ierr) CHKERRQ(ierr) - call SNESSetConvergenceTest(mechanical_snes,converged,PETSC_NULL_SNES,PETSC_NULL_FUNCTION,ierr) ! specify custom convergence check function "_converged" + call SNESSetConvergenceTest(mechanical_snes,converged,PETSC_NULL_SNES,PETSC_NULL_FUNCTION,ierr) ! specify custom convergence check function "_converged" CHKERRQ(ierr) - call SNESSetMaxLinearSolveFailures(mechanical_snes, huge(1), ierr) ! ignore linear solve failures + call SNESSetMaxLinearSolveFailures(mechanical_snes, huge(1), ierr) ! ignore linear solve failures CHKERRQ(ierr) - call SNESSetFromOptions(mechanical_snes,ierr) ! pull it all together with additional cli arguments + call SNESSetFromOptions(mechanical_snes,ierr) ! pull it all together with additional cli arguments CHKERRQ(ierr) !-------------------------------------------------------------------------------------------------- @@ -489,10 +489,8 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,fnorm,reason,dummy,i divTol = max(maxval(abs(P_av))*num%eps_div_rtol ,num%eps_div_atol) BCTol = max(maxval(abs(P_av))*num%eps_stress_rtol,num%eps_stress_atol) - if (terminallyIll .or. & - (totalIter >= num%itmin .and. & - all([ err_div/divTol, & - err_BC /BCTol ] < 1.0_pReal))) then + if ((totalIter >= num%itmin .and. all([err_div/divTol, err_BC/BCTol] < 1.0_pReal)) & + .or. terminallyIll) then reason = 1 elseif (totalIter >= num%itmax) then reason = -1 diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index c8896e2eb..ba435300a 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -424,10 +424,8 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,devNull3,reason,dumm divTol = max(maxval(abs(P_av))*num%eps_div_rtol ,num%eps_div_atol) BCTol = max(maxval(abs(P_av))*num%eps_stress_rtol,num%eps_stress_atol) - if ((totalIter >= num%itmin .and. & - all([ err_div/divTol, & - err_BC /BCTol ] < 1.0_pReal)) & - .or. terminallyIll) then + if ((totalIter >= num%itmin .and. all([err_div/divTol, err_BC/BCTol] < 1.0_pReal)) & + .or. terminallyIll) then reason = 1 elseif (totalIter >= num%itmax) then reason = -1 diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index 5c26fc85c..388588743 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -483,11 +483,8 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,devNull3,reason,dumm divTol = max(maxval(abs(P_av)) *num%eps_div_rtol ,num%eps_div_atol) BCTol = max(maxval(abs(P_av)) *num%eps_stress_rtol,num%eps_stress_atol) - if (terminallyIll .or. & - (totalIter >= num%itmin .and. & - all([ err_div /divTol, & - err_curl/curlTol, & - err_BC /BCTol ] < 1.0_pReal))) then + if ((totalIter >= num%itmin .and. all([err_div/divTol, err_curl/curlTol, err_BC/BCTol] < 1.0_pReal)) & + .or. terminallyIll) then reason = 1 elseif (totalIter >= num%itmax) then reason = -1 From 84e383964bd67390b374cf84057ffcf53ff713d5 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 27 Mar 2021 23:58:49 +0100 Subject: [PATCH 050/219] polishing/fixing tests --- PRIVATE | 2 +- examples/config/Phase_Damage.config | 2 -- examples/config/Source_Damage_IsoBrittle.config | 5 ----- src/mesh/DAMASK_mesh.f90 | 6 +++--- 4 files changed, 4 insertions(+), 11 deletions(-) delete mode 100644 examples/config/Phase_Damage.config delete mode 100644 examples/config/Source_Damage_IsoBrittle.config diff --git a/PRIVATE b/PRIVATE index 535310ae7..c55d060b4 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 535310ae792895d1eca5d45af335cd7e227af145 +Subproject commit c55d060b409c8a610b7fe8722fb756c1ed93c7ad diff --git a/examples/config/Phase_Damage.config b/examples/config/Phase_Damage.config deleted file mode 100644 index f34a78627..000000000 --- a/examples/config/Phase_Damage.config +++ /dev/null @@ -1,2 +0,0 @@ -damage_diffusion11 1.0 -damage_mobility 0.001 diff --git a/examples/config/Source_Damage_IsoBrittle.config b/examples/config/Source_Damage_IsoBrittle.config deleted file mode 100644 index b36165ab4..000000000 --- a/examples/config/Source_Damage_IsoBrittle.config +++ /dev/null @@ -1,5 +0,0 @@ -(source) damage_isoBrittle -isobrittle_criticalStrainEnergy 1400000.0 -isobrittle_atol 0.01 -isobrittle_N 1.0 -(output) isoBrittle_DrivingForce diff --git a/src/mesh/DAMASK_mesh.f90 b/src/mesh/DAMASK_mesh.f90 index 5ef0f7a36..ed99d1143 100644 --- a/src/mesh/DAMASK_mesh.f90 +++ b/src/mesh/DAMASK_mesh.f90 @@ -338,15 +338,15 @@ program DAMASK_mesh cutBack = .False. if(.not. all(solres(:)%converged .and. solres(:)%stagConverged)) then ! no solution found if (cutBackLevel < maxCutBack) then ! do cut back - print'(/,a)', ' cut back detected' cutBack = .True. stepFraction = (stepFraction - 1) * subStepFactor ! adjust to new denominator cutBackLevel = cutBackLevel + 1 time = time - timeinc ! rewind time timeinc = timeinc/2.0_pReal + print'(/,a)', ' cutting back' else ! default behavior, exit if spectral solver does not converge - call IO_warning(850) - call quit(1) ! quit + if (worldrank == 0) close(statUnit) + call IO_error(950) endif else guess = .true. ! start guessing after first converged (sub)inc From a3ab89031539e7bd06f0ce67ed1c988bcf5b63bf Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 28 Mar 2021 11:35:40 +0200 Subject: [PATCH 051/219] bugfix for ConfigMaterial don't use mutable variables in python initializers, they get updated --- python/damask/_configmaterial.py | 10 ++++------ python/damask/_rotation.py | 22 ++++++++++++++++------ python/damask/_table.py | 15 ++++++++------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index a5fe837ee..2d57b268d 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -18,21 +18,19 @@ class ConfigMaterial(Config): stored as 'material.yaml'. """ - _defaults = {'material': [], - 'homogenization': {}, - 'phase': {}} - def __init__(self,d=_defaults): + def __init__(self,d=None): """ New material configuration. Parameters ---------- d : dictionary, optional - Initial content. Defaults to empty material, homogenization, and phase entries. + Initial content. Defaults to None, in which case empty entries for + material, homogenization, and phase are created. """ - super().__init__(d) + super().__init__({'material': [], 'homogenization': {}, 'phase': {}} if d is None else d) def save(self,fname='material.yaml',**kwargs): diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index ec231348b..a067209b2 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -29,16 +29,26 @@ class Rotation: Examples -------- - Rotate vector "a" (defined in coordinate system "A") to - coordinates "b" expressed in system "B": + Rotate vector 'a' (defined in coordinate system 'A') to + coordinates 'b' expressed in system 'B': - - b = Q @ a - - b = np.dot(Q.as_matrix(),a) + >>> import damask + >>> import numpy as np + >>> Q = damask.Rotation.from_random() + >>> a = np.random.rand(3) + >>> b = R @ a + >>> np.allclose(np.dot(Q.as_matrix(),a),b) + True Compound rotations R1 (first) and R2 (second): - - R = R2 * R1 - - R = Rotation.from_matrix(np.dot(R2.as_matrix(),R1.as_matrix()) + >>> import damask + >>> import numpy as np + >>> R1 = damask.Rotation.from_random() + >>> R2 = damask.Rotation.from_random() + >>> R = R2 * R1 + >>> np.allclose(R.as_matrix(), np.dot(R2.as_matrix(),R1.as_matrix())) + True References ---------- diff --git a/python/damask/_table.py b/python/damask/_table.py index fef84cca5..25b38e78c 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -126,13 +126,14 @@ class Table: Load from ang file. A valid TSL ang file needs to contains the following columns: - * Euler angles (Bunge notation) in radians, 3 floats, label 'eu'. - * Spatial position in meters, 2 floats, label 'pos'. - * Image quality, 1 float, label 'IQ'. - * Confidence index, 1 float, label 'CI'. - * Phase ID, 1 int, label 'ID'. - * SEM signal, 1 float, label 'intensity'. - * Fit, 1 float, label 'fit'. + + - Euler angles (Bunge notation) in radians, 3 floats, label 'eu'. + - Spatial position in meters, 2 floats, label 'pos'. + - Image quality, 1 float, label 'IQ'. + - Confidence index, 1 float, label 'CI'. + - Phase ID, 1 int, label 'ID'. + - SEM signal, 1 float, label 'intensity'. + - Fit, 1 float, label 'fit'. Parameters ---------- From a587e707040b46934a426841e43710d161a1fddc Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 28 Mar 2021 11:37:47 +0200 Subject: [PATCH 052/219] split into small sections and test damage --- PRIVATE | 2 +- .../Phase_None_IsotropicVolumePreservation.config | 8 -------- examples/config/Phase_Nonlocal_Aluminum.config | 2 -- examples/config/phase/Al.yaml | 4 ++++ examples/config/phase/Fe.yaml | 4 ++++ examples/config/phase/Ni.yaml | 4 ++++ examples/config/phase/damage/anisobrittle_cubic.yaml | 8 ++++++++ .../config/phase/mechanical/elastic/Hooke_Fe.yaml | 8 ++++++++ examples/config/phase/thermal/adiabatic.yaml | 4 ++++ .../config/phase/thermal/externalheat_adiabatic.yaml | 11 ----------- .../phase/thermal/externalheat_fast-convection.yaml | 11 ----------- examples/config/phase/thermal/fast-convection.yaml | 4 ++++ .../phase/thermal/source/dissipation_generic.yaml | 2 ++ .../thermal/source/externalheat_ramp-and-hold.yaml | 3 +++ python/damask/_configmaterial.py | 2 +- 15 files changed, 43 insertions(+), 34 deletions(-) delete mode 100644 examples/config/Phase_None_IsotropicVolumePreservation.config create mode 100644 examples/config/phase/Al.yaml create mode 100644 examples/config/phase/Fe.yaml create mode 100644 examples/config/phase/Ni.yaml create mode 100644 examples/config/phase/damage/anisobrittle_cubic.yaml create mode 100644 examples/config/phase/mechanical/elastic/Hooke_Fe.yaml create mode 100644 examples/config/phase/thermal/adiabatic.yaml delete mode 100644 examples/config/phase/thermal/externalheat_adiabatic.yaml delete mode 100644 examples/config/phase/thermal/externalheat_fast-convection.yaml create mode 100644 examples/config/phase/thermal/fast-convection.yaml create mode 100644 examples/config/phase/thermal/source/dissipation_generic.yaml create mode 100644 examples/config/phase/thermal/source/externalheat_ramp-and-hold.yaml diff --git a/PRIVATE b/PRIVATE index c55d060b4..4d7be2f3a 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit c55d060b409c8a610b7fe8722fb756c1ed93c7ad +Subproject commit 4d7be2f3a65e709ecd04b60ac0abd352f4c2208e diff --git a/examples/config/Phase_None_IsotropicVolumePreservation.config b/examples/config/Phase_None_IsotropicVolumePreservation.config deleted file mode 100644 index 46c99985f..000000000 --- a/examples/config/Phase_None_IsotropicVolumePreservation.config +++ /dev/null @@ -1,8 +0,0 @@ -[IsotropicVolumePreservation] -elasticity hooke -plasticity none - -### Material parameters ### -lattice_structure iso -C11 100.0e9 -C12 66.6666667e9 diff --git a/examples/config/Phase_Nonlocal_Aluminum.config b/examples/config/Phase_Nonlocal_Aluminum.config index 500dcf69d..c69d2fd67 100644 --- a/examples/config/Phase_Nonlocal_Aluminum.config +++ b/examples/config/Phase_Nonlocal_Aluminum.config @@ -1,6 +1,4 @@ [Aluminum] - -elasticity hooke plasticity nonlocal /nonlocal/ diff --git a/examples/config/phase/Al.yaml b/examples/config/phase/Al.yaml new file mode 100644 index 000000000..9d6daf88f --- /dev/null +++ b/examples/config/phase/Al.yaml @@ -0,0 +1,4 @@ +lattice: cF +rho: 2700 +references: + - en.wikipedia.org/wiki/Aluminium diff --git a/examples/config/phase/Fe.yaml b/examples/config/phase/Fe.yaml new file mode 100644 index 000000000..e8d39fdbe --- /dev/null +++ b/examples/config/phase/Fe.yaml @@ -0,0 +1,4 @@ +lattice: cI +rho: 7874 +references: + - en.wikipedia.org/wiki/Iron diff --git a/examples/config/phase/Ni.yaml b/examples/config/phase/Ni.yaml new file mode 100644 index 000000000..49adb9e11 --- /dev/null +++ b/examples/config/phase/Ni.yaml @@ -0,0 +1,4 @@ +lattice: cF +rho: 8908 +references: + - en.wikipedia.org/wiki/Nickel diff --git a/examples/config/phase/damage/anisobrittle_cubic.yaml b/examples/config/phase/damage/anisobrittle_cubic.yaml new file mode 100644 index 000000000..410bcf2c3 --- /dev/null +++ b/examples/config/phase/damage/anisobrittle_cubic.yaml @@ -0,0 +1,8 @@ +N_cl: [3] +dot_o: 1e-3 +g_crit: [0.50e7] +q: 20 +s_crit: [0.006666] +type: anisobrittle +D_11: 1.0 +M: 0.001 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml b/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml new file mode 100644 index 000000000..0e5d7db5c --- /dev/null +++ b/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml @@ -0,0 +1,8 @@ +type: Hooke +references: + - J.P. Hirth and J. Lothe, + Theory of Dislocations, 1982, + John Wiley & Sons +C_11: 242e9 +C_12: 146.5e9 +C_44: 11.2e9 diff --git a/examples/config/phase/thermal/adiabatic.yaml b/examples/config/phase/thermal/adiabatic.yaml new file mode 100644 index 000000000..c0956cb0d --- /dev/null +++ b/examples/config/phase/thermal/adiabatic.yaml @@ -0,0 +1,4 @@ +c_p: 1 +K_11: 0 +K_22: 0 +K_33: 0 diff --git a/examples/config/phase/thermal/externalheat_adiabatic.yaml b/examples/config/phase/thermal/externalheat_adiabatic.yaml deleted file mode 100644 index e34f4fc5b..000000000 --- a/examples/config/phase/thermal/externalheat_adiabatic.yaml +++ /dev/null @@ -1,11 +0,0 @@ -adiabatic: - rho: 1 - thermal: - c_p: 1 - K_11: 0 - K_22: 0 - K_33: 0 - source: - - type: externalheat - f_T: [1, 1, 0, 0] - t_n: [0, 500, 500.001, 1000] diff --git a/examples/config/phase/thermal/externalheat_fast-convection.yaml b/examples/config/phase/thermal/externalheat_fast-convection.yaml deleted file mode 100644 index c7f2df61b..000000000 --- a/examples/config/phase/thermal/externalheat_fast-convection.yaml +++ /dev/null @@ -1,11 +0,0 @@ -fast-convection: - rho: 1 - thermal: - c_p: 1 - K_11: 1e30 - K_22: 1e30 - K_33: 1e30 - source: - - type: externalheat - f_T: [1, 1, 0, 0] - t_n: [0, 500, 500.001, 1000] diff --git a/examples/config/phase/thermal/fast-convection.yaml b/examples/config/phase/thermal/fast-convection.yaml new file mode 100644 index 000000000..c266acf1e --- /dev/null +++ b/examples/config/phase/thermal/fast-convection.yaml @@ -0,0 +1,4 @@ +c_p: 1 +K_11: 1e30 +K_22: 1e30 +K_33: 1e30 diff --git a/examples/config/phase/thermal/source/dissipation_generic.yaml b/examples/config/phase/thermal/source/dissipation_generic.yaml new file mode 100644 index 000000000..af5214582 --- /dev/null +++ b/examples/config/phase/thermal/source/dissipation_generic.yaml @@ -0,0 +1,2 @@ +type: dissipation +kappa: .9 diff --git a/examples/config/phase/thermal/source/externalheat_ramp-and-hold.yaml b/examples/config/phase/thermal/source/externalheat_ramp-and-hold.yaml new file mode 100644 index 000000000..333ece989 --- /dev/null +++ b/examples/config/phase/thermal/source/externalheat_ramp-and-hold.yaml @@ -0,0 +1,3 @@ +type: externalheat +f_T: [1, 1, 0, 0] +t_n: [0, 500, 500.001, 1000] diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index 2d57b268d..e2762be4d 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -16,9 +16,9 @@ class ConfigMaterial(Config): A complete material configuration file has the entries 'material', 'phase', and 'homogenization'. For use in DAMASK, it needs to be stored as 'material.yaml'. + """ - def __init__(self,d=None): """ New material configuration. From 5ea2fa97a08ed092f6bbf6f5c4f106d46749de10 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 28 Mar 2021 12:46:26 +0200 Subject: [PATCH 053/219] untested and unused code --- .gitlab-ci.yml | 2 +- python/damask/_test.py | 178 ----------------------------------------- 2 files changed, 1 insertion(+), 179 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 71d181977..c322b57d8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -97,7 +97,7 @@ processing: script: - cd $DAMASKROOT/python - pytest --basetemp=${TESTROOT}/python -v --cov --cov-report=term - - coverage report --fail-under=85 + - coverage report --fail-under=90 except: - master - release diff --git a/python/damask/_test.py b/python/damask/_test.py index d5c946034..162241d30 100644 --- a/python/damask/_test.py +++ b/python/damask/_test.py @@ -85,7 +85,6 @@ class Test: def execute(self): """Run all variants and report first failure.""" if not self.options.keep: - if not self.feasible(): return -1 self.clean() self.prepareAll() @@ -114,10 +113,6 @@ class Test: return variant+1 # return culprit return 0 - def feasible(self): - """Check whether test is possible or not (e.g. no license available).""" - return True - def clean(self): """Delete directory tree containing current results.""" try: @@ -172,11 +167,6 @@ class Test: return os.path.normpath(os.path.join(self.dirBase,'current/')) - def dirProof(self): - """Directory containing human readable proof of correctness for the test.""" - return os.path.normpath(os.path.join(self.dirBase,'proof/')) - - def fileInRoot(self,dir,file): """Path to a file in the root directory of DAMASK.""" return str(Path(os.environ['DAMASK_ROOT'])/dir/file) @@ -192,11 +182,6 @@ class Test: return os.path.join(self.dirCurrent(),file) - def fileInProof(self,file): - """Path to a file in the proof directory for the test.""" - return os.path.join(self.dirProof(),file) - - def copy(self, mapA, mapB, A = [], B = []): """ @@ -249,17 +234,6 @@ class Test: raise FileNotFoundError - def copy_Proof2Current(self,sourcefiles=[],targetfiles=[]): - - if len(targetfiles) == 0: targetfiles = sourcefiles - for i,f in enumerate(sourcefiles): - try: - shutil.copy2(self.fileInProof(f),self.fileInCurrent(targetfiles[i])) - except FileNotFoundError: - logging.critical(f'Proof2Current: Unable to copy file "{f}"') - raise FileNotFoundError - - def copy_Current2Current(self,sourcefiles=[],targetfiles=[]): for i,f in enumerate(sourcefiles): @@ -281,158 +255,6 @@ class Test: return out,error - def compare_Table(self,headings0,file0, - headings1,file1, - normHeadings='',normType=None, - absoluteTolerance=False,perLine=False,skipLines=[]): - - import numpy as np - logging.info('\n '.join(['comparing ASCII Tables',file0,file1])) - if normHeadings == '': normHeadings = headings0 - -# check if comparison is possible and determine length of columns - if len(headings0) == len(headings1) == len(normHeadings): - dataLength = len(headings0) - length = [1 for i in range(dataLength)] - shape = [[] for i in range(dataLength)] - data = [[] for i in range(dataLength)] - maxError = [0.0 for i in range(dataLength)] - absTol = [absoluteTolerance for i in range(dataLength)] - column = [[1 for i in range(dataLength)] for j in range(2)] - - norm = [[] for i in range(dataLength)] - normLength = [1 for i in range(dataLength)] - normShape = [[] for i in range(dataLength)] - normColumn = [1 for i in range(dataLength)] - - for i in range(dataLength): - if headings0[i]['shape'] != headings1[i]['shape']: - raise Exception(f"shape mismatch between {headings0[i]['label']} and {headings1[i]['label']}") - shape[i] = headings0[i]['shape'] - for j in range(np.shape(shape[i])[0]): - length[i] *= shape[i][j] - normShape[i] = normHeadings[i]['shape'] - for j in range(np.shape(normShape[i])[0]): - normLength[i] *= normShape[i][j] - else: - raise Exception(f'trying to compare {len(headings0)} with {len(headings1)} normed by {len(normHeadings)} data sets') - - table0 = damask.ASCIItable(name=file0,readonly=True) - table0.head_read() - table1 = damask.ASCIItable(name=file1,readonly=True) - table1.head_read() - - for i in range(dataLength): - key0 = ('1_' if length[i]>1 else '') + headings0[i]['label'] - key1 = ('1_' if length[i]>1 else '') + headings1[i]['label'] - normKey = ('1_' if normLength[i]>1 else '') + normHeadings[i]['label'] - if key0 not in table0.labels(raw = True): - raise Exception(f'column "{key0}" not found in first table...') - elif key1 not in table1.labels(raw = True): - raise Exception(f'column "{key1}" not found in second table...') - elif normKey not in table0.labels(raw = True): - raise Exception(f'column "{normKey}" not found in first table...') - else: - column[0][i] = table0.label_index(key0) - column[1][i] = table1.label_index(key1) - normColumn[i] = table0.label_index(normKey) - - line0 = 0 - while table0.data_read(): # read next data line of ASCII table - if line0 not in skipLines: - for i in range(dataLength): - myData = np.array(list(map(float,table0.data[column[0][i]:\ - column[0][i]+length[i]])),'d') - normData = np.array(list(map(float,table0.data[normColumn[i]:\ - normColumn[i]+normLength[i]])),'d') - data[i] = np.append(data[i],np.reshape(myData,shape[i])) - if normType == 'pInf': - norm[i] = np.append(norm[i],np.max(np.abs(normData))) - else: - norm[i] = np.append(norm[i],np.linalg.norm(np.reshape(normData,normShape[i]),normType)) - line0 += 1 - - for i in range(dataLength): - if not perLine: norm[i] = [np.max(norm[i]) for j in range(line0-len(skipLines))] - data[i] = np.reshape(data[i],[line0-len(skipLines),length[i]]) - if any(norm[i]) == 0.0 or absTol[i]: - norm[i] = [1.0 for j in range(line0-len(skipLines))] - absTol[i] = True - logging.warning(f'''{"At least one" if perLine else "Maximum"} norm of - "{headings0[i]['label']}" in first table is 0.0, using absolute tolerance''') - - line1 = 0 - while table1.data_read(): # read next data line of ASCII table - if line1 not in skipLines: - for i in range(dataLength): - myData = np.array(list(map(float,table1.data[column[1][i]:\ - column[1][i]+length[i]])),'d') - maxError[i] = max(maxError[i],np.linalg.norm(np.reshape(myData-data[i][line1-len(skipLines),:],shape[i]))/ - norm[i][line1-len(skipLines)]) - line1 +=1 - - if (line0 != line1): raise Exception(f'found {line0} lines in first table but {line1} in second table') - - logging.info(' ********') - for i in range(dataLength): - logging.info(f''' * maximum {'absolute' if absTol[i] else 'relative'} error {maxError[i]} - between {headings0[i]['label']} and {headings1[i]['label']}''') - logging.info(' ********') - return maxError - - - def compare_TablesStatistically(self, - files = [None,None], # list of file names - columns = [None], # list of list of column labels (per file) - meanTol = 1.0e-4, - stdTol = 1.0e-6, - preFilter = 1.0e-9): - """ - Calculate statistics of tables. - - threshold can be used to ignore small values (a negative number disables this feature) - """ - if not (isinstance(files, Iterable) and not isinstance(files, str)): # check whether list of files is requested - files = [str(files)] - - tables = [damask.Table.load(filename) for filename in files] - for table in tables: - table._label_discrete() - - columns += [columns[0]]*(len(files)-len(columns)) # extend to same length as files - columns = columns[:len(files)] # truncate to same length as files - - for i,column in enumerate(columns): - if column is None: columns[i] = list(tables[i].data.columns) # if no column is given, read all - - logging.info('comparing ASCIItables statistically') - for i in range(len(columns)): - columns[i] = columns[0] if not columns[i] else \ - ([columns[i]] if not (isinstance(columns[i], Iterable) and not isinstance(columns[i], str)) else \ - columns[i] - ) - logging.info(files[i]+':'+','.join(columns[i])) - - if len(files) < 2: return True # single table is always close to itself... - - data = [] - for table,labels in zip(tables,columns): - table._label_uniform() - data.append(np.hstack(list(table.get(label) for label in labels))) - - - for i in range(1,len(data)): - delta = data[i]-data[i-1] - normBy = (np.abs(data[i]) + np.abs(data[i-1]))*0.5 - normedDelta = np.where(normBy>preFilter,delta/normBy,0.0) - mean = np.amax(np.abs(np.mean(normedDelta,0))) - std = np.amax(np.std(normedDelta,0)) - logging.info(f'mean: {mean:f}') - logging.info(f'std: {std:f}') - - return (mean < meanTol) & (std < stdTol) - - def report_Success(self,culprit): ret = culprit From 942d398e40ebced472722257d59d9516a58f9574 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 28 Mar 2021 13:36:33 +0200 Subject: [PATCH 054/219] duplicate of YAML-based config file --- examples/config/Source_Thermal_Dissipation.config | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 examples/config/Source_Thermal_Dissipation.config diff --git a/examples/config/Source_Thermal_Dissipation.config b/examples/config/Source_Thermal_Dissipation.config deleted file mode 100644 index 6d7647410..000000000 --- a/examples/config/Source_Thermal_Dissipation.config +++ /dev/null @@ -1,2 +0,0 @@ -(source) thermal_dissipation -dissipation_ColdWorkCoeff 0.95 From a17074b3658773c15c73abcc9ce6fe191a0e7e7c Mon Sep 17 00:00:00 2001 From: Test User Date: Sun, 28 Mar 2021 17:04:21 +0200 Subject: [PATCH 055/219] [skip ci] updated version information after successful test of v3.0.0-alpha2-662-gb36ff26cb --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 2a83b7331..6a9c51c19 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-653-g3d4590a52 +v3.0.0-alpha2-662-gb36ff26cb From 3fe1accf1819ae4db7631f9c323a5063d8512c8e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 28 Mar 2021 19:48:44 +0200 Subject: [PATCH 056/219] not used anymore --- python/damask/_test.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/python/damask/_test.py b/python/damask/_test.py index 162241d30..f9a17b3ab 100644 --- a/python/damask/_test.py +++ b/python/damask/_test.py @@ -3,12 +3,9 @@ import sys import shutil import logging import logging.config -from collections.abc import Iterable from optparse import OptionParser from pathlib import Path -import numpy as np - import damask class Test: From e6143f6eec9628509f6c0db0083402c61e682fa1 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 29 Mar 2021 06:34:55 +0200 Subject: [PATCH 057/219] source not needed here I don't think 'shape' is possible without full inspection of the stored data structure --- src/YAML_types.f90 | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index 88efaf9d1..02a0bc435 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -260,10 +260,10 @@ subroutine selfTest allocate(tList::l3) select type(l3) class is(tList) - call l3%append(s3) + call l3%append(s3) call l3%append(s4) - endselect - + endselect + allocate(tList::l2) select type(l2) class is(tList) @@ -539,7 +539,7 @@ end function tNode_get_byIndex_asString !-------------------------------------------------------------------------------------------------- -!> @brief Access by index and convert to float array +!> @brief Access by index and convert to float array (1D) !-------------------------------------------------------------------------------------------------- function tNode_get_byIndex_as1dFloat(self,i) result(nodeAs1dFloat) @@ -558,7 +558,7 @@ end function tNode_get_byIndex_as1dFloat !-------------------------------------------------------------------------------------------------- -!> @brief Access by index and convert to int array +!> @brief Access by index and convert to int array (1D) !-------------------------------------------------------------------------------------------------- function tNode_get_byIndex_as1dInt(self,i) result(nodeAs1dInt) @@ -577,7 +577,7 @@ end function tNode_get_byIndex_as1dInt !-------------------------------------------------------------------------------------------------- -!> @brief Access by index and convert to bool array +!> @brief Access by index and convert to bool array (1D) !-------------------------------------------------------------------------------------------------- function tNode_get_byIndex_as1dBool(self,i) result(nodeAs1dBool) @@ -596,7 +596,7 @@ end function tNode_get_byIndex_as1dBool !-------------------------------------------------------------------------------------------------- -!> @brief Access by index and convert to string array +!> @brief Access by index and convert to string array (1D) !-------------------------------------------------------------------------------------------------- function tNode_get_byIndex_as1dString(self,i) result(nodeAs1dString) @@ -823,7 +823,7 @@ end function tNode_get_byKey_asString !-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to float array +!> @brief Access by key and convert to float array (1D) !-------------------------------------------------------------------------------------------------- function tNode_get_byKey_as1dFloat(self,k,defaultVal,requiredSize) result(nodeAs1dFloat) @@ -855,7 +855,7 @@ end function tNode_get_byKey_as1dFloat !-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to 2D float array +!> @brief Access by key and convert to float array (2D) !-------------------------------------------------------------------------------------------------- function tNode_get_byKey_as2dFloat(self,k,defaultVal) result(nodeAs2dFloat) @@ -882,7 +882,7 @@ end function tNode_get_byKey_as2dFloat !-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to int array +!> @brief Access by key and convert to int array (1D) !-------------------------------------------------------------------------------------------------- function tNode_get_byKey_as1dInt(self,k,defaultVal,requiredSize) result(nodeAs1dInt) @@ -913,7 +913,7 @@ end function tNode_get_byKey_as1dInt !-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to bool array +!> @brief Access by key and convert to bool array (1D) !-------------------------------------------------------------------------------------------------- function tNode_get_byKey_as1dBool(self,k,defaultVal) result(nodeAs1dBool) @@ -939,7 +939,7 @@ end function tNode_get_byKey_as1dBool !-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to string array +!> @brief Access by key and convert to string array (1D) !-------------------------------------------------------------------------------------------------- function tNode_get_byKey_as1dString(self,k,defaultVal) result(nodeAs1dString) @@ -965,7 +965,7 @@ end function tNode_get_byKey_as1dString !-------------------------------------------------------------------------------------------------- -!> @brief Returns string output array (hack for GNU) +!> @brief Returns string output array (1D) (hack for GNU) !-------------------------------------------------------------------------------------------------- function output_as1dString(self) result(output) !ToDo: SR: Remove whenever GNU works @@ -1146,7 +1146,7 @@ end function tScalar_asString !-------------------------------------------------------------------------------------------------- -!> @brief Convert to float array +!> @brief Convert to float array (1D) !-------------------------------------------------------------------------------------------------- function tList_as1dFloat(self) @@ -1169,7 +1169,7 @@ end function tList_as1dFloat !-------------------------------------------------------------------------------------------------- -!> @brief Convert to 2D float array +!> @brief Convert to float array (2D) !-------------------------------------------------------------------------------------------------- function tList_as2dFloat(self) @@ -1180,22 +1180,22 @@ function tList_as2dFloat(self) class(tNode), pointer :: row type(tList), pointer :: row_data - row => self%get(1) !SR: some interface called 'shape' may be used? + row => self%get(1) row_data => row%asList() - allocate(tList_as2dFloat(self%length,row_data%length),source=0.0_pReal) + allocate(tList_as2dFloat(self%length,row_data%length)) do i=1,self%length row => self%get(i) row_data => row%asList() if(row_data%length /= size(tList_as2dFloat,2)) call IO_error(709,ext_msg='Varying number of columns') - tList_as2dFloat(i,:) = self%get_as1dFloat(i) + tList_as2dFloat(i,:) = self%get_as1dFloat(i) enddo end function tList_as2dFloat !-------------------------------------------------------------------------------------------------- -!> @brief Convert to int array +!> @brief Convert to int array (1D) !-------------------------------------------------------------------------------------------------- function tList_as1dInt(self) @@ -1218,7 +1218,7 @@ end function tList_as1dInt !-------------------------------------------------------------------------------------------------- -!> @brief Convert to bool array +!> @brief Convert to bool array (1D) !-------------------------------------------------------------------------------------------------- function tList_as1dBool(self) @@ -1241,7 +1241,7 @@ end function tList_as1dBool !-------------------------------------------------------------------------------------------------- -!> @brief Convert to string array +!> @brief Convert to string array (1D) !-------------------------------------------------------------------------------------------------- function tList_as1dString(self) From a2b2f8fb134f8b6e77c3baf5f2f32c57c178d53b Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 29 Mar 2021 07:07:11 +0200 Subject: [PATCH 058/219] include latest results --- PRIVATE | 2 +- .../plastic/dislotwin_IF-steel.yaml | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml diff --git a/PRIVATE b/PRIVATE index 4d7be2f3a..62e2b5bed 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 4d7be2f3a65e709ecd04b60ac0abd352f4c2208e +Subproject commit 62e2b5bed89723649d4cabebe5fc191d05a40321 diff --git a/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml b/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml new file mode 100644 index 000000000..9d0c5be8b --- /dev/null +++ b/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml @@ -0,0 +1,23 @@ +type: dislotwin +references: + - K. Sedighiani et al., + International Journal of Plasticity, 134, 102779, 2020 + 10.1016/j.ijplas.2020.102779 + - K. Sedighiani et al., + Mechanics of Materials, submitted +N_sl: [12, 12] +b_sl: [2.49e-10, 2.49e-10] +rho_mob_0: [2.81e12, 2.8e12] +rho_dip_0: [1.0, 1.0] # not given +v_0: [1.4e3, 1.4e3] +Q_s: [1.57e-19, 1.57e-19] # Delta_F +tau_0: [454e6, 454e6] +p_sl: [0.325, 0.325] +q_sl: [1.55, 1.55] +i_sl: [23.3, 23.3] +D_a: 7.4 # C_anni +B: [0.001, 0.001] +h_sl_sl: [0.1, 0.1, 0.72, 0.053, 0.137, 0.073] +D_0: 4.000E-05 +Q_cl: 5.400E-19 # no recovery! +D: 40e-6 # estimated From b44864355dcdd55dc047fec2f270dce309988dc2 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 29 Mar 2021 07:16:15 +0200 Subject: [PATCH 059/219] no need for subscript, following dislotwin --- src/phase_mechanical_plastic_phenopowerlaw.f90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/phase_mechanical_plastic_phenopowerlaw.f90 b/src/phase_mechanical_plastic_phenopowerlaw.f90 index c91524812..dbe2101e6 100644 --- a/src/phase_mechanical_plastic_phenopowerlaw.f90 +++ b/src/phase_mechanical_plastic_phenopowerlaw.f90 @@ -24,7 +24,7 @@ submodule(phase:plastic) phenopowerlaw real(pReal), allocatable, dimension(:) :: & xi_inf_sl, & !< maximum critical shear stress for slip h_int, & !< per family hardening activity (optional) - gamma_tw_char !< characteristic shear for twins + gamma_char !< characteristic shear for twins real(pReal), allocatable, dimension(:,:) :: & h_sl_sl, & !< slip resistance from slip activity h_sl_tw, & !< slip resistance from twin activity @@ -169,7 +169,7 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) prm%h_tw_tw = lattice_interaction_TwinByTwin(N_tw,& pl%get_asFloats('h_tw_tw'), & phase%get_asString('lattice')) - prm%gamma_tw_char = lattice_characteristicShear_twin(N_tw,phase%get_asString('lattice'),& + prm%gamma_char = lattice_characteristicShear_twin(N_tw,phase%get_asString('lattice'),& phase%get_asFloat('c/a',defaultVal=0.0_pReal)) xi_0_tw = pl%get_asFloats('xi_0_tw',requiredSize=size(N_tw)) @@ -192,7 +192,7 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) else twinActive xi_0_tw = emptyRealArray - allocate(prm%gamma_tw_char,source=emptyRealArray) + allocate(prm%gamma_char,source=emptyRealArray) allocate(prm%h_tw_tw(0,0)) endif twinActive @@ -354,7 +354,7 @@ module subroutine phenopowerlaw_dotState(Mp,ph,me) dot => dotState(ph)) sumGamma = sum(stt%gamma_slip(:,me)) - sumF = sum(stt%gamma_twin(:,me)/prm%gamma_tw_char) + sumF = sum(stt%gamma_twin(:,me)/prm%gamma_char) !-------------------------------------------------------------------------------------------------- ! system-independent (nonlinear) prefactors to M_Xx (X influenced by x) matrices @@ -524,7 +524,7 @@ pure subroutine kinetics_twin(Mp,ph,me,& enddo where(tau_twin > 0.0_pReal) - gdot_twin = (1.0_pReal-sum(stt%gamma_twin(:,me)/prm%gamma_tw_char)) & ! only twin in untwinned volume fraction + gdot_twin = (1.0_pReal-sum(stt%gamma_twin(:,me)/prm%gamma_char)) & ! only twin in untwinned volume fraction * prm%dot_gamma_0_tw*(abs(tau_twin)/stt%xi_twin(:,me))**prm%n_tw else where gdot_twin = 0.0_pReal From 5bf4553882d1bcf65fa791d738edeac395aa29d1 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 29 Mar 2021 07:25:55 +0200 Subject: [PATCH 060/219] following naming of interaction coefficients --- PRIVATE | 2 +- examples/config/Phase_Phenopowerlaw_Magnesium.yaml | 2 +- src/phase_mechanical_plastic_phenopowerlaw.f90 | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/PRIVATE b/PRIVATE index 62e2b5bed..4511a963d 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 62e2b5bed89723649d4cabebe5fc191d05a40321 +Subproject commit 4511a963da5094db309a6a68783f24a23c76da81 diff --git a/examples/config/Phase_Phenopowerlaw_Magnesium.yaml b/examples/config/Phase_Phenopowerlaw_Magnesium.yaml index 6540fb880..d42cca09f 100644 --- a/examples/config/Phase_Phenopowerlaw_Magnesium.yaml +++ b/examples/config/Phase_Phenopowerlaw_Magnesium.yaml @@ -25,4 +25,4 @@ Magnesium: dot_gamma_0_tw: 0.001 n_sl: 20 n_tw: 20 - f_sl_sat_tw: 10.0 + f_sat_sl_tw: 10.0 diff --git a/src/phase_mechanical_plastic_phenopowerlaw.f90 b/src/phase_mechanical_plastic_phenopowerlaw.f90 index dbe2101e6..6c40c9a8f 100644 --- a/src/phase_mechanical_plastic_phenopowerlaw.f90 +++ b/src/phase_mechanical_plastic_phenopowerlaw.f90 @@ -12,7 +12,7 @@ submodule(phase:plastic) phenopowerlaw dot_gamma_0_tw = 1.0_pReal, & !< reference shear strain rate for twin n_sl = 1.0_pReal, & !< stress exponent for slip n_tw = 1.0_pReal, & !< stress exponent for twin - f_sl_sat_tw = 1.0_pReal, & !< push-up factor for slip saturation due to twinning + f_sat_sl_tw = 1.0_pReal, & !< push-up factor for slip saturation due to twinning c_1 = 1.0_pReal, & c_2 = 1.0_pReal, & c_3 = 1.0_pReal, & @@ -180,7 +180,7 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) prm%c_4 = pl%get_asFloat('c_4',defaultVal=0.0_pReal) prm%dot_gamma_0_tw = pl%get_asFloat('dot_gamma_0_tw') prm%n_tw = pl%get_asFloat('n_tw') - prm%f_sl_sat_tw = pl%get_asFloat('f_sl_sat_tw') + prm%f_sat_sl_tw = pl%get_asFloat('f_sat_sl_tw') prm%h_0_tw_tw = pl%get_asFloat('h_0_tw_tw') ! expand: family => system @@ -365,7 +365,7 @@ module subroutine phenopowerlaw_dotState(Mp,ph,me) !-------------------------------------------------------------------------------------------------- ! calculate left and right vectors left_SlipSlip = 1.0_pReal + prm%h_int - xi_slip_sat_offset = prm%f_sl_sat_tw*sqrt(sumF) + xi_slip_sat_offset = prm%f_sat_sl_tw*sqrt(sumF) right_SlipSlip = abs(1.0_pReal-stt%xi_slip(:,me) / (prm%xi_inf_sl+xi_slip_sat_offset)) **prm%a_sl & * sign(1.0_pReal,1.0_pReal-stt%xi_slip(:,me) / (prm%xi_inf_sl+xi_slip_sat_offset)) From 03d54be58a073f27ca7544af45aebb2d6a0fa16e Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 29 Mar 2021 08:21:53 +0200 Subject: [PATCH 061/219] [skip ci] updated version information after successful test of v3.0.0-alpha2-670-ge6143f6ee --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6a9c51c19..445e4606c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-662-gb36ff26cb +v3.0.0-alpha2-670-ge6143f6ee From aa5cd76d33c1e4728bdcc454b5bb1312061cf8a3 Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Mon, 29 Mar 2021 13:47:23 +0200 Subject: [PATCH 062/219] function not needed --- src/YAML_types.f90 | 345 ++++++++++++++++++++------------------------- 1 file changed, 154 insertions(+), 191 deletions(-) diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index 9c5214164..5ee9325b4 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -20,16 +20,10 @@ module YAML_types procedure(asFormattedString), deferred :: asFormattedString procedure :: & asScalar => tNode_asScalar - procedure :: & - isScalar => tNode_isScalar procedure :: & asList => tNode_asList - procedure :: & - isList => tNode_isList procedure :: & asDict => tNode_asDict - procedure :: & - isDict => tNode_isDict procedure :: & tNode_get_byIndex => tNode_get_byIndex procedure :: & @@ -347,57 +341,6 @@ function tNode_asDict(self) result(dict) end function tNode_asDict -!-------------------------------------------------------------------------------------------------- -!> @brief Checks if node is a scalar -!-------------------------------------------------------------------------------------------------- -function tNode_isScalar(self) result(scalar) - - class(tNode), intent(in), target :: self - logical :: scalar - - scalar = .false. - select type(self) - class is(tScalar) - scalar = .true. - end select - -end function tNode_isScalar - - -!-------------------------------------------------------------------------------------------------- -!> @brief Checks if node is a list -!-------------------------------------------------------------------------------------------------- -function tNode_isList(self) result(list) - - class(tNode), intent(in), target :: self - logical :: list - - list = .false. - select type(self) - class is(tList) - list = .true. - end select - -end function tNode_isList - - -!-------------------------------------------------------------------------------------------------- -!> @brief Checks if node is a dict -!-------------------------------------------------------------------------------------------------- -function tNode_isDict(self) result(dict) - - class(tNode), intent(in), target :: self - logical :: dict - - dict = .false. - select type(self) - class is(tDict) - dict = .true. - end select - -end function tNode_isDict - - !-------------------------------------------------------------------------------------------------- !> @brief Access by index !-------------------------------------------------------------------------------------------------- @@ -411,11 +354,12 @@ function tNode_get_byIndex(self,i) result(node) class(tItem), pointer :: item integer :: j - if (self%isList()) then - self_ => self%asList() - else - call IO_error(706,ext_msg='Expected List') - endif + select type(self) + class is(tList) + self_ => self%asList() + class default + call IO_error(706,ext_msg='Expected List') + endselect item => self_%first @@ -442,12 +386,13 @@ function tNode_get_byIndex_asFloat(self,i) result(nodeAsFloat) type(tScalar), pointer :: scalar node => self%get(i) - if (node%isScalar()) then - scalar => node%asScalar() - nodeAsFloat = scalar%asFloat() - else - call IO_error(706,ext_msg='Expected Scalar') - endif + select type(node) + class is(tScalar) + scalar => node%asScalar() + nodeAsFloat = scalar%asFloat() + class default + call IO_error(706,ext_msg='Expected Scalar') + end select end function tNode_get_byIndex_asFloat @@ -465,12 +410,13 @@ function tNode_get_byIndex_asInt(self,i) result(nodeAsInt) type(tScalar), pointer :: scalar node => self%get(i) - if (node%isScalar()) then - scalar => node%asScalar() - nodeAsInt = scalar%asInt() - else - call IO_error(706,ext_msg='Expected Scalar') - endif + select type(node) + class is(tScalar) + scalar => node%asScalar() + nodeAsInt = scalar%asInt() + class default + call IO_error(706,ext_msg='Expected Scalar') + end select end function tNode_get_byIndex_asInt @@ -488,12 +434,13 @@ function tNode_get_byIndex_asBool(self,i) result(nodeAsBool) type(tScalar), pointer :: scalar node => self%get(i) - if (node%isScalar()) then - scalar => node%asScalar() - nodeAsBool = scalar%asBool() - else - call IO_error(706,ext_msg='Expected Scalar') - endif + select type(node) + class is(tScalar) + scalar => node%asScalar() + nodeAsBool = scalar%asBool() + class default + call IO_error(706,ext_msg='Expected Scalar') + endselect end function tNode_get_byIndex_asBool @@ -511,12 +458,13 @@ function tNode_get_byIndex_asString(self,i) result(nodeAsString) type(tScalar), pointer :: scalar node => self%get(i) - if (node%isScalar()) then - scalar => node%asScalar() - nodeAsString = scalar%asString() - else - call IO_error(706,ext_msg='Expected Scalar') - endif + select type(node) + class is(tScalar) + scalar => node%asScalar() + nodeAsString = scalar%asString() + class default + call IO_error(706,ext_msg='Expected Scalar') + endselect end function tNode_get_byIndex_asString @@ -534,12 +482,13 @@ function tNode_get_byIndex_asFloats(self,i) result(nodeAsFloats) class(tList), pointer :: list node => self%get(i) - if (node%isList()) then - list => node%asList() - nodeAsFloats = list%asFloats() - else - call IO_error(706,ext_msg='Expected list') - endif + select type(node) + class is(tList) + list => node%asList() + nodeAsFloats = list%asFloats() + class default + call IO_error(706,ext_msg='Expected list') + endselect end function tNode_get_byIndex_asFloats @@ -557,12 +506,13 @@ function tNode_get_byIndex_asInts(self,i) result(nodeAsInts) class(tList), pointer :: list node => self%get(i) - if (node%isList()) then - list => node%asList() - nodeAsInts = list%asInts() - else - call IO_error(706,ext_msg='Expected list') - endif + select type(node) + class is(tList) + list => node%asList() + nodeAsInts = list%asInts() + class default + call IO_error(706,ext_msg='Expected list') + endselect end function tNode_get_byIndex_asInts @@ -580,12 +530,13 @@ function tNode_get_byIndex_asBools(self,i) result(nodeAsBools) class(tList), pointer :: list node => self%get(i) - if (node%isList()) then - list => node%asList() - nodeAsBools = list%asBools() - else - call IO_error(706,ext_msg='Expected list') - endif + select type(node) + class is(tList) + list => node%asList() + nodeAsBools = list%asBools() + class default + call IO_error(706,ext_msg='Expected list') + endselect end function tNode_get_byIndex_asBools @@ -603,12 +554,13 @@ function tNode_get_byIndex_asStrings(self,i) result(nodeAsStrings) type(tList), pointer :: list node => self%get(i) - if (node%isList()) then - list => node%asList() - nodeAsStrings = list%asStrings() - else - call IO_error(706,ext_msg='Expected list') - endif + select type(node) + class is(tList) + list => node%asList() + nodeAsStrings = list%asStrings() + class default + call IO_error(706,ext_msg='Expected list') + endselect end function tNode_get_byIndex_asStrings @@ -626,15 +578,16 @@ function tNode_get_byIndex_asKey(self,i) result(key) type(tDict), pointer :: dict type(tItem), pointer :: item - if (self%isDict()) then - dict => self%asDict() - item => dict%first - do j = 1, min(i,dict%length)-1 - item => item%next - enddo - else - call IO_error(706,ext_msg='Expected dict') - endif + select type(self) + class is(tDict) + dict => self%asDict() + item => dict%first + do j = 1, min(i,dict%length)-1 + item => item%next + enddo + class default + call IO_error(706,ext_msg='Expected dict') + endselect key = item%key @@ -655,25 +608,26 @@ function tNode_contains(self,k) result(exists) type(tDict), pointer :: dict exists = .false. - if (self%isDict()) then - dict => self%asDict() - do j=1, dict%length - if (dict%getKey(j) == k) then - exists = .true. - return - endif - enddo - elseif (self%isList()) then - list => self%asList() - do j=1, list%length - if (list%get_asString(j) == k) then - exists = .true. - return - endif - enddo - else - call IO_error(706,ext_msg='Expected "list" or "dict"') - endif + select type(self) + class is(tDict) + dict => self%asDict() + do j=1, dict%length + if (dict%getKey(j) == k) then + exists = .true. + return + endif + enddo + class is(tList) + list => self%asList() + do j=1, list%length + if (list%get_asString(j) == k) then + exists = .true. + return + endif + enddo + class default + call IO_error(706,ext_msg='Expected "list" or "dict"') + endselect end function tNode_contains @@ -696,11 +650,12 @@ function tNode_get_byKey(self,k,defaultVal) result(node) found = present(defaultVal) if (found) node => defaultVal - if (self%isDict()) then - self_ => self%asDict() - else - call IO_error(706,ext_msg='Expected Dict for key '//k) - endif + select type(self) + class is(tDict) + self_ => self%asDict() + class default + call IO_error(706,ext_msg='Expected Dict for key '//k) + endselect j = 1 item => self_%first @@ -738,12 +693,13 @@ function tNode_get_byKey_asFloat(self,k,defaultVal) result(nodeAsFloat) if (self%contains(k)) then node => self%get(k) - if (node%isScalar()) then - scalar => node%asScalar() - nodeAsFloat = scalar%asFloat() - else - call IO_error(706,ext_msg='Expected Scalar for key '//k) - endif + select type(node) + class is(tScalar) + scalar => node%asScalar() + nodeAsFloat = scalar%asFloat() + class default + call IO_error(706,ext_msg='Expected Scalar for key '//k) + endselect elseif (present(defaultVal)) then nodeAsFloat = defaultVal else @@ -768,12 +724,13 @@ function tNode_get_byKey_asInt(self,k,defaultVal) result(nodeAsInt) if (self%contains(k)) then node => self%get(k) - if (node%isScalar()) then - scalar => node%asScalar() - nodeAsInt = scalar%asInt() - else - call IO_error(706,ext_msg='Expected Scalar for key '//k) - endif + select type(node) + class is(tScalar) + scalar => node%asScalar() + nodeAsInt = scalar%asInt() + class default + call IO_error(706,ext_msg='Expected Scalar for key '//k) + endselect elseif (present(defaultVal)) then nodeAsInt = defaultVal else @@ -798,12 +755,13 @@ function tNode_get_byKey_asBool(self,k,defaultVal) result(nodeAsBool) if (self%contains(k)) then node => self%get(k) - if (node%isScalar()) then - scalar => node%asScalar() - nodeAsBool = scalar%asBool() - else - call IO_error(706,ext_msg='Expected Scalar for key '//k) - endif + select type(node) + class is(tScalar) + scalar => node%asScalar() + nodeAsBool = scalar%asBool() + class default + call IO_error(706,ext_msg='Expected Scalar for key '//k) + endselect elseif (present(defaultVal)) then nodeAsBool = defaultVal else @@ -828,12 +786,13 @@ function tNode_get_byKey_asString(self,k,defaultVal) result(nodeAsString) if (self%contains(k)) then node => self%get(k) - if (node%isScalar()) then - scalar => node%asScalar() - nodeAsString = scalar%asString() - else - call IO_error(706,ext_msg='Expected Scalar for key '//k) - endif + select type(node) + class is(tScalar) + scalar => node%asScalar() + nodeAsString = scalar%asString() + class default + call IO_error(706,ext_msg='Expected Scalar for key '//k) + endselect elseif (present(defaultVal)) then nodeAsString = defaultVal else @@ -860,12 +819,13 @@ function tNode_get_byKey_asFloats(self,k,defaultVal,requiredSize) result(nodeAsF if (self%contains(k)) then node => self%get(k) - if (node%isList()) then - list => node%asList() - nodeAsFloats = list%asFloats() - else - call IO_error(706,ext_msg='Expected list for key '//k) - endif + select type(self) + class is(tList) + list => node%asList() + nodeAsFloats = list%asFloats() + class default + call IO_error(706,ext_msg='Expected list for key '//k) + endselect elseif (present(defaultVal)) then nodeAsFloats = defaultVal else @@ -895,12 +855,13 @@ function tNode_get_byKey_asInts(self,k,defaultVal,requiredSize) result(nodeAsInt if (self%contains(k)) then node => self%get(k) - if (node%isList()) then - list => node%asList() - nodeAsInts = list%asInts() - else - call IO_error(706,ext_msg='Expected list for key '//k) - endif + select type(node) + class is(tList) + list => node%asList() + nodeAsInts = list%asInts() + class default + call IO_error(706,ext_msg='Expected list for key '//k) + endselect elseif (present(defaultVal)) then nodeAsInts = defaultVal else @@ -929,12 +890,13 @@ function tNode_get_byKey_asBools(self,k,defaultVal) result(nodeAsBools) if (self%contains(k)) then node => self%get(k) - if (node%isList())then - list => node%asList() - nodeAsBools = list%asBools() - else - call IO_error(706,ext_msg='Expected list for key '//k) - endif + select type(node) + class is(tList) + list => node%asList() + nodeAsBools = list%asBools() + class default + call IO_error(706,ext_msg='Expected list for key '//k) + endselect elseif (present(defaultVal)) then nodeAsBools = defaultVal else @@ -959,12 +921,13 @@ function tNode_get_byKey_asStrings(self,k,defaultVal) result(nodeAsStrings) if (self%contains(k)) then node => self%get(k) - if (node%isList()) then - list => node%asList() - nodeAsStrings = list%asStrings() - else - call IO_error(706,ext_msg='Expected list for key '//k) - endif + select type(node) + class is(tList) + list => node%asList() + nodeAsStrings = list%asStrings() + class default + call IO_error(706,ext_msg='Expected list for key '//k) + endselect elseif (present(defaultVal)) then nodeAsStrings = defaultVal else From 295c03664400518f62ae2dc021a0589a79d3cf5f Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Mon, 29 Mar 2021 20:10:57 +0200 Subject: [PATCH 063/219] not required (checking) --- src/phase_mechanical.f90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index bde894507..1dea21d36 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -1213,8 +1213,6 @@ module function crystallite_stress(dt,co,ip,el) result(converged_) if (todo) then subF = subF0 & + subStep * (phase_mechanical_F(ph)%data(1:3,1:3,me) - phase_mechanical_F0(ph)%data(1:3,1:3,me)) - phase_mechanical_Fe(ph)%data(1:3,1:3,me) = matmul(subF,math_inv33(matmul(phase_mechanical_Fi(ph)%data(1:3,1:3,me), & - phase_mechanical_Fp(ph)%data(1:3,1:3,me)))) converged_ = .not. integrateState(subF0,subF,subFp0,subFi0,subState0(1:sizeDotState),subStep * dt,co,ip,el) converged_ = converged_ .and. .not. integrateDamageState(subStep * dt,co,ip,el) endif From 7e8f630a6260fadb4cfa82b5984699e03c686a4f Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Mon, 29 Mar 2021 21:44:37 +0200 Subject: [PATCH 064/219] consistent --- src/YAML_types.f90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index 72262f1ad..eff5f2483 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -855,7 +855,7 @@ function tNode_get_byKey_as1dFloat(self,k,defaultVal,requiredSize) result(nodeAs list => node%asList() nodeAs1dFloat = list%as1dFloat() class default - call IO_error(706,ext_msg='Expected 1D list for key '//k) + call IO_error(706,ext_msg='Expected 1D Float array for key '//k) endselect elseif (present(defaultVal)) then nodeAs1dFloat = defaultVal @@ -891,7 +891,7 @@ function tNode_get_byKey_as2dFloat(self,k,defaultVal) result(nodeAs2dFloat) rows => node%asList() nodeAs2dFloat = rows%as2dFloat() class default - call IO_error(706,ext_msg='Expected 2D list for key '//k) + call IO_error(706,ext_msg='Expected 2D Float array for key '//k) endselect elseif(present(defaultVal)) then nodeAs2dFloat = defaultVal @@ -923,7 +923,7 @@ function tNode_get_byKey_as1dInt(self,k,defaultVal,requiredSize) result(nodeAs1d list => node%asList() nodeAs1dInt = list%as1dInt() class default - call IO_error(706,ext_msg='Expected list for key '//k) + call IO_error(706,ext_msg='Expected 1D Integer array for key '//k) endselect elseif (present(defaultVal)) then nodeAs1dInt = defaultVal @@ -958,7 +958,7 @@ function tNode_get_byKey_as1dBool(self,k,defaultVal) result(nodeAs1dBool) list => node%asList() nodeAs1dBool = list%as1dBool() class default - call IO_error(706,ext_msg='Expected list for key '//k) + call IO_error(706,ext_msg='Expected 1D Boolean array for key '//k) endselect elseif (present(defaultVal)) then nodeAs1dBool = defaultVal @@ -989,7 +989,7 @@ function tNode_get_byKey_as1dString(self,k,defaultVal) result(nodeAs1dString) list => node%asList() nodeAs1dString = list%as1dString() class default - call IO_error(706,ext_msg='Expected list for key '//k) + call IO_error(706,ext_msg='Expected 1D String array for key '//k) endselect elseif (present(defaultVal)) then nodeAs1dString = defaultVal From b19ec4f8ae0f0f12c089fbe66b879c3d48099fbc Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 30 Mar 2021 07:24:47 +0200 Subject: [PATCH 065/219] first ideas for more user friendly usage --- python/damask/_result.py | 141 ++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 70 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 415ddded9..3affa2af8 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -11,6 +11,7 @@ from collections import defaultdict import h5py import numpy as np +import numpy.ma as ma from numpy.lib import recfunctions as rfn import damask @@ -345,76 +346,6 @@ class Result: raise PermissionError('Rename operation not permitted') - def place(self,datasets,constituent=0,tagged=False,split=True): - """ - Distribute datasets onto geometry and return Table or (split) dictionary of Tables. - - Must not mix nodal end cell data. - - Only data within - - inc*/phase/*/* - - inc*/homogenization/*/* - - inc*/geometry/* - are considered. - - Parameters - ---------- - datasets : iterable or str - constituent : int - Constituent to consider for phase data. - tagged : bool - Tag Table.column name with '#constituent'. - Defaults to False. - split : bool - Split Table by increment and return dictionary of Tables. - Defaults to True. - - """ - sets = datasets if hasattr(datasets,'__iter__') and not isinstance(datasets,str) else \ - [datasets] - tag = f'#{constituent}' if tagged else '' - tbl = {} if split else None - inGeom = {} - inData = {} - # compatibility hack - name = 'Name' if self.version_minor < 12 else 'label' - member = 'Position' if self.version_minor < 12 else 'entry' - grp = 'mapping' if self.version_minor < 12 else 'cell_to' - with h5py.File(self.fname,'r') as f: - for dataset in sets: - for group in self.groups_with_datasets(dataset): - path = '/'.join([group,dataset]) - inc,prop,name,cat,item = (path.split('/') + ['']*5)[:5] - key = '/'.join([prop,name+tag]) - if key not in inGeom: - if prop == 'geometry': - inGeom[key] = inData[key] = np.arange(self.N_materialpoints) - elif prop == 'phase': - inGeom[key] = np.where(f[f'{grp}/phase'][:,constituent][name] == str.encode(name))[0] - inData[key] = f[f'{grp}/phase'][inGeom[key],constituent][member] - elif prop == 'homogenization': - inGeom[key] = np.where(f[f'{grp}/homogenization'][name] == str.encode(name))[0] - inData[key] = f[f'{grp}/homogenization'][inGeom[key].tolist()][member] - shape = np.shape(f[path]) - data = np.full((self.N_materialpoints,) + (shape[1:] if len(shape)>1 else (1,)), - np.nan, - dtype=np.dtype(f[path])) - data[inGeom[key]] = (f[path] if len(shape)>1 else np.expand_dims(f[path],1))[inData[key]] - path = ('/'.join([prop,name]+([cat] if cat else [])+([item] if item else [])) if split else path)+tag - if split: - try: - tbl[inc] = tbl[inc].add(path,data) - except KeyError: - tbl[inc] = Table(data.reshape(self.N_materialpoints,-1),{path:data.shape[1:]}) - else: - try: - tbl = tbl.add(path,data) - except AttributeError: - tbl = Table(data.reshape(self.N_materialpoints,-1),{path:data.shape[1:]}) - - return tbl - - def groups_with_datasets(self,datasets): """ Return groups that contain all requested datasets. @@ -1385,3 +1316,73 @@ class Result: v.add(u,'u') v.save(f'{self.fname.stem}_inc{inc[ln:].zfill(N_digits)}') + + + def read(self,labels): + r = {} + labels_ = labels if isinstance(labels,list) else [labels] # check for arbitrary iterable + with h5py.File(self.fname,'r') as f: + for inc in util.show_progress(self.visible['increments'],len(self.visible['increments'])): + r[inc] = {'phase':{},'homogenization':{}} + for ph in self.visible['phases']: + r[inc]['phase'][ph] = {} + for me in f[os.path.join(inc,'phase',ph)].keys(): + r[inc]['phase'][ph][me] = {} + for da in f[os.path.join(inc,'phase',ph,me)].keys(): + if da in labels_: + r[inc]['phase'][ph][me][da] = \ + f[os.path.join(inc,'phase',ph,me,da)][()] + for ho in self.visible['homogenizations']: + r[inc]['homogenization'][ho] = {} + for me in f[os.path.join(inc,'homogenization',ho)].keys(): + r[inc]['homogenization'][ho][me] = {} + for da in f[os.path.join(inc,'homogenization',ho,me)].keys(): + if da in labels_: + r[inc]['homogenization'][ho][me][da] = \ + f[os.path.join(inc,'homogenization',ho,me,da)][()] + return r + + + def place(self,labels,fill_int=0,fill_float=0,constituents=None): + r = {} + + labels_ = labels if isinstance(labels,list) else [labels] # check for arbitrary iterable + if constituents is None: + constituents_ = range(self.N_constituents) + else: + constituents_ = labels if isinstance(labels,list) else [labels] # allow abribtrary iterable + + + grp = 'mapping' if self.version_minor < 12 else 'cell_to' + name = 'Name' if self.version_minor < 12 else 'label' + + with h5py.File(self.fname,'r') as f: + N_cells = self.cells.prod() if self.structured else np.shape(f['/geometry/T_c'])[0] + + to_cell_ph = [] + for c in constituents_: + to_cell_ph.append({label: np.where(f[os.path.join(grp,'phase')][:,c][name] == str.encode(label))[0] \ + for label in self.visible['phases']}) + to_cell_ho = {label: np.where(f[os.path.join(grp,'homogenization')][name] == str.encode(label))[0] \ + for label in self.visible['homogenizations']} + + for inc in util.show_progress(self.visible['increments'],len(self.visible['increments'])): + r[inc] = {'phase':{},'homogenization':{}} + for ph in self.visible['phases']: + for me in f[os.path.join(inc,'phase',ph)].keys(): + r[inc]['phase'][me] = {} + for da in f[os.path.join(inc,'phase',ph,me)].keys(): + if da in labels_: + data = f[os.path.join(inc,'phase',ph,me,da)][()] + + unit = f[os.path.join(inc,'phase',ph,me,da)].attrs['unit'] + description = f[os.path.join(inc,'phase',ph,me,da)].attrs['description'] + if not h5py3: + description = description.decode() + unit = unit.decode() + + if da not in r[inc]['phase'][me].keys(): + dt = np.dtype(data.dtype,metadata={'description':description, + 'unit':unit}) + r[inc]['phase'][me][da] = ma.empty((N_cells,)+data.shape[1:],dtype=dt) + return r From d1af4b031acce9e1165666fb501f4703b2a08973 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 30 Mar 2021 17:02:57 +0200 Subject: [PATCH 066/219] source for python-compatible versioning --- python/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/setup.py b/python/setup.py index 0642c0b7d..f6ba83b7b 100644 --- a/python/setup.py +++ b/python/setup.py @@ -2,6 +2,7 @@ import setuptools from pathlib import Path import re +# https://www.python.org/dev/peps/pep-0440 with open(Path(__file__).parent/'damask/VERSION') as f: version = re.sub(r'(-([^-]*)).*$',r'.\2',re.sub(r'^v(\d+\.\d+(\.\d+)?)',r'\1',f.readline().strip())) From b9b66fac45b4ea34ea6f44bd19aabbbc79b7ef31 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 30 Mar 2021 17:15:02 +0200 Subject: [PATCH 067/219] simplified --- python/damask/_result.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 415ddded9..ba726d4d3 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -139,8 +139,7 @@ class Result: datasets = ['*'] elif datasets is False: datasets = [] - choice = datasets if hasattr(datasets,'__iter__') and not isinstance(datasets,str) else \ - [datasets] + choice = [datasets] if isinstance(datasets,str) else datasets.copy() inc = 'inc' if self.version_minor < 12 else 'increment_' # compatibility hack if what == 'increments': From 7865092b821bc41227036d319ae1985e9d0be667 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 30 Mar 2021 17:24:19 +0200 Subject: [PATCH 068/219] not needed --- python/damask/_configmaterial.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index e2762be4d..dedf4373b 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -1,4 +1,4 @@ -import os.path +import os import numpy as np import h5py From 989992004dfcc142a408cba2b8ccf7f0e2193397 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 30 Mar 2021 19:41:36 +0200 Subject: [PATCH 069/219] cleaning dicts --- python/damask/_result.py | 11 +++++++---- python/damask/util.py | 21 +++++++++++++++++++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 3affa2af8..e832ad573 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1318,11 +1318,11 @@ class Result: v.save(f'{self.fname.stem}_inc{inc[ln:].zfill(N_digits)}') - def read(self,labels): + def read(self,labels,compress=True,strip=True): r = {} - labels_ = labels if isinstance(labels,list) else [labels] # check for arbitrary iterable + labels_ = [labels] if isinstance(labels,str) else labels with h5py.File(self.fname,'r') as f: - for inc in util.show_progress(self.visible['increments'],len(self.visible['increments'])): + for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{}} for ph in self.visible['phases']: r[inc]['phase'][ph] = {} @@ -1340,13 +1340,16 @@ class Result: if da in labels_: r[inc]['homogenization'][ho][me][da] = \ f[os.path.join(inc,'homogenization',ho,me,da)][()] + + if strip: r = util.dict_strip(r) + return r def place(self,labels,fill_int=0,fill_float=0,constituents=None): r = {} - labels_ = labels if isinstance(labels,list) else [labels] # check for arbitrary iterable + labels_ = [labels] if isinstance(labels,str) else labels if constituents is None: constituents_ = range(self.N_constituents) else: diff --git a/python/damask/util.py b/python/damask/util.py index 902e0409c..3f0846588 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -25,7 +25,8 @@ __all__=[ 'execution_stamp', 'shapeshifter', 'shapeblender', 'extend_docstring', 'extended_docstring', - 'DREAM3D_base_group', 'DREAM3D_cell_data_group' + 'DREAM3D_base_group', 'DREAM3D_cell_data_group', + 'dict_strip', 'dict_compress' ] # https://svn.blender.org/svnroot/bf-blender/trunk/blender/build_files/scons/tools/bcolors.py @@ -130,7 +131,7 @@ def show_progress(iterable,N_iter=None,prefix='',bar_length=50): Character length of bar. Defaults to 50. """ - status = _ProgressBar(N_iter if N_iter else len(iterable),prefix,bar_length) + status = _ProgressBar(N_iter if N_iter is not None else len(iterable),prefix,bar_length) for i,item in enumerate(iterable): yield item @@ -398,6 +399,22 @@ def DREAM3D_cell_data_group(fname): return cell_data_group +def dict_strip(a_dict): + # https://stackoverflow.com/questions/48151953 + new_dict = {} + for k, v in a_dict.items(): + if isinstance(v, dict): + v = dict_strip(v) + if not isinstance(v,dict) or v != {}: + new_dict[k] = v + return new_dict + + +def dict_compress(a_dict): + + + return None + #################################################################################################### # Classes From c43dc0cb9530774756e46fc8defdaa4ff711350c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 30 Mar 2021 19:45:35 +0200 Subject: [PATCH 070/219] better log --- .gitlab-ci.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c322b57d8..3f33842a4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -96,7 +96,7 @@ processing: stage: python script: - cd $DAMASKROOT/python - - pytest --basetemp=${TESTROOT}/python -v --cov --cov-report=term + - COLUMS=256 pytest --basetemp=${TESTROOT}/python -v --cov --cov-report=term - coverage report --fail-under=90 except: - master @@ -116,7 +116,7 @@ compile_grid_Intel: script: - module load $IntelCompiler $MPI_Intel $PETSc_Intel - cd pytest - - pytest -k 'compile and grid' --basetemp=${TESTROOT}/compile_grid_Intel + - COLUMNS=256 pytest -k 'compile and grid' --basetemp=${TESTROOT}/compile_grid_Intel except: - master - release @@ -126,7 +126,7 @@ compile_mesh_Intel: script: - module load $IntelCompiler $MPI_Intel $PETSc_Intel - cd pytest - - pytest -k 'compile and mesh' --basetemp=${TESTROOT}/compile_mesh_Intel + - COLUMNS=256 pytest -k 'compile and mesh' --basetemp=${TESTROOT}/compile_mesh_Intel except: - master - release @@ -136,7 +136,7 @@ compile_grid_GNU: script: - module load $GNUCompiler $MPI_GNU $PETSc_GNU - cd pytest - - pytest -k 'compile and grid' --basetemp=${TESTROOT}/compile_grid_GNU + - COLUMNS=256 pytest -k 'compile and grid' --basetemp=${TESTROOT}/compile_grid_GNU except: - master - release @@ -146,7 +146,7 @@ compile_mesh_GNU: script: - module load $GNUCompiler $MPI_GNU $PETSc_GNU - cd pytest - - pytest -k 'compile and mesh' --basetemp=${TESTROOT}/compile_mesh_GNU + - COLUMNS=256 pytest -k 'compile and mesh' --basetemp=${TESTROOT}/compile_mesh_GNU except: - master - release @@ -156,7 +156,7 @@ compile_Marc: script: - module load $IntelMarc $HDF5Marc $MSC - cd pytest - - pytest -k 'compile and Marc' --basetemp=${TESTROOT}/compile_Marc + - COLUMNS=256 pytest -k 'compile and Marc' --basetemp=${TESTROOT}/compile_Marc except: - master - release @@ -191,7 +191,7 @@ core: script: - module load $IntelCompiler $MPI_Intel $PETSc_Intel - cd pytest - - pytest -k 'not compile' --basetemp=${TESTROOT}/fortran -v + - COLUMNS=256 pytest -k 'not compile' --basetemp=${TESTROOT}/fortran -v except: - master - release From 60119c13002b36730bcc5c3f5bc850a45b110e4b Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 30 Mar 2021 21:39:14 +0200 Subject: [PATCH 071/219] return minimal unique dictionaries per default --- python/damask/_result.py | 8 +++++--- python/damask/util.py | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index e832ad573..1a301a27c 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1342,18 +1342,18 @@ class Result: f[os.path.join(inc,'homogenization',ho,me,da)][()] if strip: r = util.dict_strip(r) - + if compress: r = util.dict_compress(r) return r - def place(self,labels,fill_int=0,fill_float=0,constituents=None): + def place(self,labels,compress=True,strip=True,constituents=None,fill_int=0,fill_float=0.0): r = {} labels_ = [labels] if isinstance(labels,str) else labels if constituents is None: constituents_ = range(self.N_constituents) else: - constituents_ = labels if isinstance(labels,list) else [labels] # allow abribtrary iterable + constituents_ = labels if isinstance(labels,list) else [labels] # fix grp = 'mapping' if self.version_minor < 12 else 'cell_to' @@ -1388,4 +1388,6 @@ class Result: dt = np.dtype(data.dtype,metadata={'description':description, 'unit':unit}) r[inc]['phase'][me][da] = ma.empty((N_cells,)+data.shape[1:],dtype=dt) + if strip: r = util.dict_strip(r) + if compress: r = util.dict_compress(r) return r diff --git a/python/damask/util.py b/python/damask/util.py index 3f0846588..735db39a0 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -411,10 +411,24 @@ def dict_strip(a_dict): def dict_compress(a_dict): + # https://stackoverflow.com/questions/48151953 + if isinstance(a_dict,dict) and len(a_dict) == 1: + key = list(a_dict.keys())[0] + entry = a_dict[key] + if isinstance(entry,dict): + new_dict = dict_compress(entry.copy()) + else: + new_dict = entry + else: + new_dict = {} + for k, v in a_dict.items(): + if isinstance(v, dict): + v = dict_compress(v) + if not isinstance(v,dict) or v != {}: + new_dict[k] = v + return new_dict - return None - #################################################################################################### # Classes From eebb050a641413f164163eb6cd6b39f504e13802 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 31 Mar 2021 07:54:23 +0200 Subject: [PATCH 072/219] simplified place seems to work --- python/damask/_result.py | 65 +++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 1a301a27c..16811736c 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -16,7 +16,6 @@ from numpy.lib import recfunctions as rfn import damask from . import VTK -from . import Table from . import Orientation from . import grid_filters from . import mechanics @@ -1320,7 +1319,7 @@ class Result: def read(self,labels,compress=True,strip=True): r = {} - labels_ = [labels] if isinstance(labels,str) else labels + labels_ = set([labels] if isinstance(labels,str) else labels) with h5py.File(self.fname,'r') as f: for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{}} @@ -1328,28 +1327,26 @@ class Result: r[inc]['phase'][ph] = {} for me in f[os.path.join(inc,'phase',ph)].keys(): r[inc]['phase'][ph][me] = {} - for da in f[os.path.join(inc,'phase',ph,me)].keys(): - if da in labels_: - r[inc]['phase'][ph][me][da] = \ - f[os.path.join(inc,'phase',ph,me,da)][()] + for la in labels_.intersection(f[os.path.join(inc,'phase',ph,me)].keys()): + r[inc]['phase'][ph][me][la] = \ + f[os.path.join(inc,'phase',ph,me,la)][()] for ho in self.visible['homogenizations']: r[inc]['homogenization'][ho] = {} for me in f[os.path.join(inc,'homogenization',ho)].keys(): r[inc]['homogenization'][ho][me] = {} - for da in f[os.path.join(inc,'homogenization',ho,me)].keys(): - if da in labels_: - r[inc]['homogenization'][ho][me][da] = \ - f[os.path.join(inc,'homogenization',ho,me,da)][()] + for la in labels_.intersection(f[os.path.join(inc,'homogenization',ho,me)].keys()): + r[inc]['homogenization'][ho][me][la] = \ + f[os.path.join(inc,'homogenization',ho,me,la)][()] if strip: r = util.dict_strip(r) if compress: r = util.dict_compress(r) return r - def place(self,labels,compress=True,strip=True,constituents=None,fill_int=0,fill_float=0.0): + def place(self,labels,compress=True,strip=True,constituents=None,fill_value=0.0): r = {} - labels_ = [labels] if isinstance(labels,str) else labels + labels_ = set([labels] if isinstance(labels,str) else labels) if constituents is None: constituents_ = range(self.N_constituents) else: @@ -1362,32 +1359,40 @@ class Result: with h5py.File(self.fname,'r') as f: N_cells = self.cells.prod() if self.structured else np.shape(f['/geometry/T_c'])[0] - to_cell_ph = [] + at_cell_ph = [] + in_data_ph = [] for c in constituents_: - to_cell_ph.append({label: np.where(f[os.path.join(grp,'phase')][:,c][name] == str.encode(label))[0] \ + at_cell_ph.append({label: np.where(f[os.path.join(grp,'phase')][:,c][name] == str.encode(label))[0] \ + for label in self.visible['phases']}) + in_data_ph.append({label: f[os.path.join(grp,'phase')]['entry'][at_cell_ph[c][label]][...,0] \ for label in self.visible['phases']}) - to_cell_ho = {label: np.where(f[os.path.join(grp,'homogenization')][name] == str.encode(label))[0] \ - for label in self.visible['homogenizations']} - for inc in util.show_progress(self.visible['increments'],len(self.visible['increments'])): + #at_cell_ho = {label: np.where(f[os.path.join(grp,'homogenization')][name] == str.encode(label))[0] \ + # for label in self.visible['homogenizations']} + + c = 0 + for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{}} for ph in self.visible['phases']: for me in f[os.path.join(inc,'phase',ph)].keys(): - r[inc]['phase'][me] = {} - for da in f[os.path.join(inc,'phase',ph,me)].keys(): - if da in labels_: - data = f[os.path.join(inc,'phase',ph,me,da)][()] + if me not in r[inc]['phase'].keys(): r[inc]['phase'][me] = {} + for la in labels_.intersection(f[os.path.join(inc,'phase',ph,me)].keys()): + data = ma.array(f[os.path.join(inc,'phase',ph,me,la)]) + + unit = f[os.path.join(inc,'phase',ph,me,la)].attrs['unit'] + description = f[os.path.join(inc,'phase',ph,me,la)].attrs['description'] + if not h5py3: + description = description.decode() + unit = unit.decode() + + if la not in r[inc]['phase'][me].keys(): + dt = np.dtype(data.dtype,metadata={'description':description, 'unit':unit}) + container = np.empty((N_cells,)+data.shape[1:],dtype=dt) + r[inc]['phase'][me][la] = ma.array(container,fill_value=fill_value,mask=True) + + r[inc]['phase'][me][la][at_cell_ph[c][ph]] = data[in_data_ph[c][ph]] - unit = f[os.path.join(inc,'phase',ph,me,da)].attrs['unit'] - description = f[os.path.join(inc,'phase',ph,me,da)].attrs['description'] - if not h5py3: - description = description.decode() - unit = unit.decode() - if da not in r[inc]['phase'][me].keys(): - dt = np.dtype(data.dtype,metadata={'description':description, - 'unit':unit}) - r[inc]['phase'][me][da] = ma.empty((N_cells,)+data.shape[1:],dtype=dt) if strip: r = util.dict_strip(r) if compress: r = util.dict_compress(r) return r From 7b846efe4ac2145363e24b78ac4f4a9a8b2dc949 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 30 Mar 2021 19:57:49 +0200 Subject: [PATCH 073/219] arguments can be int, bool, str --- python/.gitignore | 1 + python/damask/_result.py | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/python/.gitignore b/python/.gitignore index 7c60e1af8..89d206b99 100644 --- a/python/.gitignore +++ b/python/.gitignore @@ -2,3 +2,4 @@ dist damask.egg-info .coverage +.coverage.* diff --git a/python/damask/_result.py b/python/damask/_result.py index ba726d4d3..b2a0dd4a1 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -125,7 +125,7 @@ class Result: Select from 'set', 'add', and 'del'. what : str Attribute to change (must be from self.visible). - datasets : list of str or bool + datasets : str, int, list of str, list of int, or bool Name of datasets as list; supports ? and * wildcards. True is equivalent to [*], False is equivalent to []. @@ -139,7 +139,8 @@ class Result: datasets = ['*'] elif datasets is False: datasets = [] - choice = [datasets] if isinstance(datasets,str) else datasets.copy() + choice = list(datasets).copy() if hasattr(datasets,'__iter__') and not isinstance(datasets,str) else \ + [datasets] inc = 'inc' if self.version_minor < 12 else 'increment_' # compatibility hack if what == 'increments': From e9c65dee7382f5f2220074d1ee20f41fec48c7e0 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 31 Mar 2021 10:59:21 +0200 Subject: [PATCH 074/219] documenting and testing --- python/damask/util.py | 52 ++++++++++++++++++++++++++------------- python/tests/test_util.py | 22 +++++++++++++++++ 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/python/damask/util.py b/python/damask/util.py index 735db39a0..b79df193a 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -399,34 +399,52 @@ def DREAM3D_cell_data_group(fname): return cell_data_group -def dict_strip(a_dict): + +def dict_strip(d): + """ + Remove recursively empty dictionaries. + + Parameters + ---------- + d : dict + dictionary. + + """ # https://stackoverflow.com/questions/48151953 - new_dict = {} - for k, v in a_dict.items(): + new = {} + for k,v in d.items(): if isinstance(v, dict): v = dict_strip(v) if not isinstance(v,dict) or v != {}: - new_dict[k] = v - return new_dict + new[k] = v + return new -def dict_compress(a_dict): - # https://stackoverflow.com/questions/48151953 - if isinstance(a_dict,dict) and len(a_dict) == 1: - key = list(a_dict.keys())[0] - entry = a_dict[key] +def dict_compress(d): + """ + Remove recursively dictionaries with one entry. + + Parameters + ---------- + d : dict + dictionary. + + """ + if isinstance(d,dict) and len(d) == 1: + key = list(d.keys())[0] + entry = d[key] if isinstance(entry,dict): - new_dict = dict_compress(entry.copy()) + new = dict_compress(entry.copy()) else: - new_dict = entry + new = entry else: - new_dict = {} - for k, v in a_dict.items(): + new = {} + for k,v in d.items(): if isinstance(v, dict): v = dict_compress(v) - if not isinstance(v,dict) or v != {}: - new_dict[k] = v - return new_dict + if not isinstance(v,dict) or v == {}: + new[k] = v + return new diff --git a/python/tests/test_util.py b/python/tests/test_util.py index b96908a9a..500e7d733 100644 --- a/python/tests/test_util.py +++ b/python/tests/test_util.py @@ -136,3 +136,25 @@ class TestUtil: else: with pytest.raises(ValueError): util.DREAM3D_cell_data_group(tmp_path/'cell_data_group.dream3d') + + + @pytest.mark.parametrize('full,reduced',[({}, {}), + ({'A':{}}, {}), + ({'A':{'B':{}}}, {}), + ({'A':{'B':'C'}},)*2, + ({'A':{'B':{},'C':'D'}}, {'A':{'C':'D'}})]) + def test_strip(self,full,reduced): + assert util.dict_strip(full) == reduced + + + @pytest.mark.parametrize('full,reduced',[({}, {}), + ({'A':{}}, {}), + ({'A':'F'}, 'F'), + ({'A':{'B':{}}}, {}), + ({'A':{'B':'C'}}, 'C'), + ({'A':1,'B':2},)*2, + ({'A':{'B':'C','D':'E'}}, {'B':'C','D':'E'}), + ({'B':'C','D':'E'},)*2, + ({'A':{'B':{},'C':'D'}}, {'B':{},'C':'D'})]) + def test_compress(self,full,reduced): + assert util.dict_compress(full) == reduced From 8c7ee5e7960dcbed3020ce39fad372992bcabde8 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 31 Mar 2021 12:05:51 +0200 Subject: [PATCH 075/219] simplified --- python/damask/_result.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 16811736c..345090cc0 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -24,6 +24,12 @@ from . import util h5py3 = h5py.__version__[0] == '3' +def _read(handle,path): + metadata = {k:(v if h5py3 else v.decode()) for k,v in handle[path].attrs.items()} + dtype = np.dtype(handle[path].dtype,metadata=metadata) + return np.array(handle[path],dtype=dtype) + + class Result: """ Manipulate and read DADF5 files. @@ -1322,21 +1328,23 @@ class Result: labels_ = set([labels] if isinstance(labels,str) else labels) with h5py.File(self.fname,'r') as f: for inc in util.show_progress(self.visible['increments']): - r[inc] = {'phase':{},'homogenization':{}} + r[inc] = {'phase':{},'homogenization':{},'geometry':{}} + for la in labels_.intersection(f[os.path.join(inc,'geometry')].keys()): + r[inc]['geometry'][la] = _read(f,os.path.join(inc,'geometry',la)) for ph in self.visible['phases']: r[inc]['phase'][ph] = {} for me in f[os.path.join(inc,'phase',ph)].keys(): r[inc]['phase'][ph][me] = {} for la in labels_.intersection(f[os.path.join(inc,'phase',ph,me)].keys()): r[inc]['phase'][ph][me][la] = \ - f[os.path.join(inc,'phase',ph,me,la)][()] + _read(f,os.path.join(inc,'phase',ph,me,la)) for ho in self.visible['homogenizations']: r[inc]['homogenization'][ho] = {} for me in f[os.path.join(inc,'homogenization',ho)].keys(): r[inc]['homogenization'][ho][me] = {} for la in labels_.intersection(f[os.path.join(inc,'homogenization',ho,me)].keys()): r[inc]['homogenization'][ho][me][la] = \ - f[os.path.join(inc,'homogenization',ho,me,la)][()] + _read(f,os.path.join(inc,'homogenization',ho,me,la)) if strip: r = util.dict_strip(r) if compress: r = util.dict_compress(r) @@ -1372,22 +1380,17 @@ class Result: c = 0 for inc in util.show_progress(self.visible['increments']): - r[inc] = {'phase':{},'homogenization':{}} + r[inc] = {'phase':{},'homogenization':{},'geometry':{}} + for la in labels_.intersection(f[os.path.join(inc,'geometry')].keys()): + r[inc]['geometry'][la] = _read(f,os.path.join(inc,'geometry',la)) for ph in self.visible['phases']: for me in f[os.path.join(inc,'phase',ph)].keys(): if me not in r[inc]['phase'].keys(): r[inc]['phase'][me] = {} for la in labels_.intersection(f[os.path.join(inc,'phase',ph,me)].keys()): - data = ma.array(f[os.path.join(inc,'phase',ph,me,la)]) - - unit = f[os.path.join(inc,'phase',ph,me,la)].attrs['unit'] - description = f[os.path.join(inc,'phase',ph,me,la)].attrs['description'] - if not h5py3: - description = description.decode() - unit = unit.decode() + data = ma.array(_read(f,os.path.join(inc,'phase',ph,me,la))) if la not in r[inc]['phase'][me].keys(): - dt = np.dtype(data.dtype,metadata={'description':description, 'unit':unit}) - container = np.empty((N_cells,)+data.shape[1:],dtype=dt) + container = np.empty((N_cells,)+data.shape[1:],dtype=data.dtype) r[inc]['phase'][me][la] = ma.array(container,fill_value=fill_value,mask=True) r[inc]['phase'][me][la][at_cell_ph[c][ph]] = data[in_data_ph[c][ph]] From 7b678af1b42802f304284c55428bd2589f1dcb97 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 31 Mar 2021 12:40:53 +0200 Subject: [PATCH 076/219] float and int are different --- python/damask/_result.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 345090cc0..209e5e07a 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1351,7 +1351,7 @@ class Result: return r - def place(self,labels,compress=True,strip=True,constituents=None,fill_value=0.0): + def place(self,labels,compress=True,strip=True,constituents=None,fill_float=0.0,fill_int=0): r = {} labels_ = set([labels] if isinstance(labels,str) else labels) @@ -1391,11 +1391,11 @@ class Result: if la not in r[inc]['phase'][me].keys(): container = np.empty((N_cells,)+data.shape[1:],dtype=data.dtype) + fill_value = fill_float if data.dtype in np.sctypes['float'] else fill_int r[inc]['phase'][me][la] = ma.array(container,fill_value=fill_value,mask=True) r[inc]['phase'][me][la][at_cell_ph[c][ph]] = data[in_data_ph[c][ph]] - if strip: r = util.dict_strip(r) if compress: r = util.dict_compress(r) return r From 97e6c397d9e961a5fe7901ed8091f04616c4f827 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 31 Mar 2021 14:27:36 +0200 Subject: [PATCH 077/219] cleaned --- python/damask/util.py | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/python/damask/util.py b/python/damask/util.py index b79df193a..a2cb94745 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -131,11 +131,15 @@ def show_progress(iterable,N_iter=None,prefix='',bar_length=50): Character length of bar. Defaults to 50. """ - status = _ProgressBar(N_iter if N_iter is not None else len(iterable),prefix,bar_length) + if N_iter == 1 or len(iterable) == 1: + for item in iterable: + yield item + else: + status = _ProgressBar(N_iter if N_iter is not None else len(iterable),prefix,bar_length) - for i,item in enumerate(iterable): - yield item - status.update(i) + for i,item in enumerate(iterable): + yield item + status.update(i) def scale_to_coprime(v): @@ -431,19 +435,11 @@ def dict_compress(d): """ if isinstance(d,dict) and len(d) == 1: - key = list(d.keys())[0] - entry = d[key] - if isinstance(entry,dict): - new = dict_compress(entry.copy()) - else: - new = entry + entry = d[list(d.keys())[0]] + new = dict_compress(entry.copy()) if isinstance(entry,dict) else entry else: - new = {} - for k,v in d.items(): - if isinstance(v, dict): - v = dict_compress(v) - if not isinstance(v,dict) or v == {}: - new[k] = v + new = {k: (dict_compress(v) if isinstance(v, dict) else v) for k,v in d.items()} + return new From be444b69ca2115d14c5cd915c6b37914860747cb Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 31 Mar 2021 15:19:23 +0200 Subject: [PATCH 078/219] include homogenization --- python/damask/_result.py | 43 ++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 209e5e07a..418dd4a92 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -8,6 +8,7 @@ import xml.dom.minidom from pathlib import Path from functools import partial from collections import defaultdict +from collections.abc import Iterable import h5py import numpy as np @@ -1326,11 +1327,14 @@ class Result: def read(self,labels,compress=True,strip=True): r = {} labels_ = set([labels] if isinstance(labels,str) else labels) + with h5py.File(self.fname,'r') as f: for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{},'geometry':{}} + for la in labels_.intersection(f[os.path.join(inc,'geometry')].keys()): r[inc]['geometry'][la] = _read(f,os.path.join(inc,'geometry',la)) + for ph in self.visible['phases']: r[inc]['phase'][ph] = {} for me in f[os.path.join(inc,'phase',ph)].keys(): @@ -1338,6 +1342,7 @@ class Result: for la in labels_.intersection(f[os.path.join(inc,'phase',ph,me)].keys()): r[inc]['phase'][ph][me][la] = \ _read(f,os.path.join(inc,'phase',ph,me,la)) + for ho in self.visible['homogenizations']: r[inc]['homogenization'][ho] = {} for me in f[os.path.join(inc,'homogenization',ho)].keys(): @@ -1358,31 +1363,36 @@ class Result: if constituents is None: constituents_ = range(self.N_constituents) else: - constituents_ = labels if isinstance(labels,list) else [labels] # fix + constituents_ = constituents if isinstance(constituents,Iterable) else [constituents] grp = 'mapping' if self.version_minor < 12 else 'cell_to' name = 'Name' if self.version_minor < 12 else 'label' + member = 'member' if self.version_minor < 12 else 'entry' with h5py.File(self.fname,'r') as f: - N_cells = self.cells.prod() if self.structured else np.shape(f['/geometry/T_c'])[0] at_cell_ph = [] in_data_ph = [] for c in constituents_: at_cell_ph.append({label: np.where(f[os.path.join(grp,'phase')][:,c][name] == str.encode(label))[0] \ for label in self.visible['phases']}) - in_data_ph.append({label: f[os.path.join(grp,'phase')]['entry'][at_cell_ph[c][label]][...,0] \ + in_data_ph.append({label: f[os.path.join(grp,'phase')][member][at_cell_ph[c][label]][...,0] \ for label in self.visible['phases']}) - #at_cell_ho = {label: np.where(f[os.path.join(grp,'homogenization')][name] == str.encode(label))[0] \ - # for label in self.visible['homogenizations']} + at_cell_ho = {label: np.where(f[os.path.join(grp,'homogenization')][:][name] == str.encode(label))[0] \ + for label in self.visible['homogenizations']} + in_data_ho = {label: f[os.path.join(grp,'homogenization')][member][at_cell_ho[label]][...,0] \ + for label in self.visible['homogenizations']} c = 0 + for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{},'geometry':{}} + for la in labels_.intersection(f[os.path.join(inc,'geometry')].keys()): r[inc]['geometry'][la] = _read(f,os.path.join(inc,'geometry',la)) + for ph in self.visible['phases']: for me in f[os.path.join(inc,'phase',ph)].keys(): if me not in r[inc]['phase'].keys(): r[inc]['phase'][me] = {} @@ -1390,12 +1400,29 @@ class Result: data = ma.array(_read(f,os.path.join(inc,'phase',ph,me,la))) if la not in r[inc]['phase'][me].keys(): - container = np.empty((N_cells,)+data.shape[1:],dtype=data.dtype) - fill_value = fill_float if data.dtype in np.sctypes['float'] else fill_int - r[inc]['phase'][me][la] = ma.array(container,fill_value=fill_value,mask=True) + container = np.empty((self.N_materialpoints,)+data.shape[1:],dtype=data.dtype) + fill_value = fill_float if data.dtype in np.sctypes['float'] else \ + fill_int + r[inc]['phase'][me][la] = \ + ma.array(container,fill_value=fill_value,mask=True) r[inc]['phase'][me][la][at_cell_ph[c][ph]] = data[in_data_ph[c][ph]] + for ho in self.visible['homogenizations']: + for me in f[os.path.join(inc,'homogenization',ho)].keys(): + if me not in r[inc]['homogenization'].keys(): r[inc]['homogenization'][me] = {} + for la in labels_.intersection(f[os.path.join(inc,'homogenization',ho,me)].keys()): + data = ma.array(_read(f,os.path.join(inc,'homogenization',ho,me,la))) + + if la not in r[inc]['homogenization'][me].keys(): + container = np.empty((self.N_materialpoints,)+data.shape[1:],dtype=data.dtype) + fill_value = fill_float if data.dtype in np.sctypes['float'] else \ + fill_int + r[inc]['homogenization'][me][la] = \ + ma.array(container,fill_value=fill_value,mask=True) + + r[inc]['homogenization'][me][la][at_cell_ho[ho]] = data[in_data_ho[ho]] + if strip: r = util.dict_strip(r) if compress: r = util.dict_compress(r) return r From 8ac4850dd3a5107d0526c6d5c90f195ebb53d3b2 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Wed, 31 Mar 2021 10:55:25 -0400 Subject: [PATCH 079/219] more consistent error messages --- src/YAML_types.f90 | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index eff5f2483..b294f9ba1 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -389,7 +389,7 @@ function tNode_get_byIndex(self,i) result(node) class is(tList) self_ => self%asList() class default - call IO_error(706,ext_msg='Expected List') + call IO_error(706,ext_msg='Expected list') endselect item => self_%first @@ -418,11 +418,11 @@ function tNode_get_byIndex_asFloat(self,i) result(nodeAsFloat) node => self%get(i) select type(node) - class is(tScalar) + class is(tScalar) scalar => node%asScalar() nodeAsFloat = scalar%asFloat() class default - call IO_error(706,ext_msg='Expected Scalar') + call IO_error(706,ext_msg='Expected scalar float') end select end function tNode_get_byIndex_asFloat @@ -446,7 +446,7 @@ function tNode_get_byIndex_asInt(self,i) result(nodeAsInt) scalar => node%asScalar() nodeAsInt = scalar%asInt() class default - call IO_error(706,ext_msg='Expected Scalar') + call IO_error(706,ext_msg='Expected scalar integer') end select end function tNode_get_byIndex_asInt @@ -470,7 +470,7 @@ function tNode_get_byIndex_asBool(self,i) result(nodeAsBool) scalar => node%asScalar() nodeAsBool = scalar%asBool() class default - call IO_error(706,ext_msg='Expected Scalar') + call IO_error(706,ext_msg='Expected scalar Boolean') endselect end function tNode_get_byIndex_asBool @@ -494,7 +494,7 @@ function tNode_get_byIndex_asString(self,i) result(nodeAsString) scalar => node%asScalar() nodeAsString = scalar%asString() class default - call IO_error(706,ext_msg='Expected Scalar') + call IO_error(706,ext_msg='Expected scalar string') endselect end function tNode_get_byIndex_asString @@ -518,7 +518,7 @@ function tNode_get_byIndex_as1dFloat(self,i) result(nodeAs1dFloat) list => node%asList() nodeAs1dFloat = list%as1dFloat() class default - call IO_error(706,ext_msg='Expected list') + call IO_error(706,ext_msg='Expected list of floats') endselect end function tNode_get_byIndex_as1dFloat @@ -542,7 +542,7 @@ function tNode_get_byIndex_as1dInt(self,i) result(nodeAs1dInt) list => node%asList() nodeAs1dInt = list%as1dInt() class default - call IO_error(706,ext_msg='Expected list') + call IO_error(706,ext_msg='Expected list of integers') endselect end function tNode_get_byIndex_as1dInt @@ -566,7 +566,7 @@ function tNode_get_byIndex_as1dBool(self,i) result(nodeAs1dBool) list => node%asList() nodeAs1dBool = list%as1dBool() class default - call IO_error(706,ext_msg='Expected list') + call IO_error(706,ext_msg='Expected list of Booleans') endselect end function tNode_get_byIndex_as1dBool @@ -590,7 +590,7 @@ function tNode_get_byIndex_as1dString(self,i) result(nodeAs1dString) list => node%asList() nodeAs1dString = list%as1dString() class default - call IO_error(706,ext_msg='Expected list') + call IO_error(706,ext_msg='Expected list of strings') endselect end function tNode_get_byIndex_as1dString @@ -619,7 +619,7 @@ function tNode_get_byIndex_asKey(self,i) result(key) class default call IO_error(706,ext_msg='Expected dict') endselect - + key = item%key end function tNode_get_byIndex_asKey @@ -657,7 +657,7 @@ function tNode_contains(self,k) result(exists) endif enddo class default - call IO_error(706,ext_msg='Expected "list" or "dict"') + call IO_error(706,ext_msg='Expected list or dict') endselect end function tNode_contains @@ -685,7 +685,7 @@ function tNode_get_byKey(self,k,defaultVal) result(node) class is(tDict) self_ => self%asDict() class default - call IO_error(706,ext_msg='Expected Dict for key '//k) + call IO_error(706,ext_msg='Expected dict for key '//k) endselect j = 1 @@ -729,7 +729,7 @@ function tNode_get_byKey_asFloat(self,k,defaultVal) result(nodeAsFloat) scalar => node%asScalar() nodeAsFloat = scalar%asFloat() class default - call IO_error(706,ext_msg='Expected Scalar for key '//k) + call IO_error(706,ext_msg='Expected scalar float for key '//k) endselect elseif (present(defaultVal)) then nodeAsFloat = defaultVal @@ -760,7 +760,7 @@ function tNode_get_byKey_asInt(self,k,defaultVal) result(nodeAsInt) scalar => node%asScalar() nodeAsInt = scalar%asInt() class default - call IO_error(706,ext_msg='Expected Scalar for key '//k) + call IO_error(706,ext_msg='Expected scalar integer for key '//k) endselect elseif (present(defaultVal)) then nodeAsInt = defaultVal @@ -791,7 +791,7 @@ function tNode_get_byKey_asBool(self,k,defaultVal) result(nodeAsBool) scalar => node%asScalar() nodeAsBool = scalar%asBool() class default - call IO_error(706,ext_msg='Expected Scalar for key '//k) + call IO_error(706,ext_msg='Expected scalar Boolean for key '//k) endselect elseif (present(defaultVal)) then nodeAsBool = defaultVal @@ -822,7 +822,7 @@ function tNode_get_byKey_asString(self,k,defaultVal) result(nodeAsString) scalar => node%asScalar() nodeAsString = scalar%asString() class default - call IO_error(706,ext_msg='Expected Scalar for key '//k) + call IO_error(706,ext_msg='Expected scalar string for key '//k) endselect elseif (present(defaultVal)) then nodeAsString = defaultVal @@ -855,7 +855,7 @@ function tNode_get_byKey_as1dFloat(self,k,defaultVal,requiredSize) result(nodeAs list => node%asList() nodeAs1dFloat = list%as1dFloat() class default - call IO_error(706,ext_msg='Expected 1D Float array for key '//k) + call IO_error(706,ext_msg='Expected 1D float array for key '//k) endselect elseif (present(defaultVal)) then nodeAs1dFloat = defaultVal @@ -891,7 +891,7 @@ function tNode_get_byKey_as2dFloat(self,k,defaultVal) result(nodeAs2dFloat) rows => node%asList() nodeAs2dFloat = rows%as2dFloat() class default - call IO_error(706,ext_msg='Expected 2D Float array for key '//k) + call IO_error(706,ext_msg='Expected 2D float array for key '//k) endselect elseif(present(defaultVal)) then nodeAs2dFloat = defaultVal @@ -923,7 +923,7 @@ function tNode_get_byKey_as1dInt(self,k,defaultVal,requiredSize) result(nodeAs1d list => node%asList() nodeAs1dInt = list%as1dInt() class default - call IO_error(706,ext_msg='Expected 1D Integer array for key '//k) + call IO_error(706,ext_msg='Expected 1D integer array for key '//k) endselect elseif (present(defaultVal)) then nodeAs1dInt = defaultVal @@ -989,7 +989,7 @@ function tNode_get_byKey_as1dString(self,k,defaultVal) result(nodeAs1dString) list => node%asList() nodeAs1dString = list%as1dString() class default - call IO_error(706,ext_msg='Expected 1D String array for key '//k) + call IO_error(706,ext_msg='Expected 1D string array for key '//k) endselect elseif (present(defaultVal)) then nodeAs1dString = defaultVal From 8a8a28adc4ceb38fa1b6aeed63a6ed925f96cd29 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 31 Mar 2021 17:11:53 +0200 Subject: [PATCH 080/219] support multi-constituents --- python/damask/_result.py | 74 ++++++++++++++++++++++++++++++++++------ python/damask/util.py | 2 +- 2 files changed, 64 insertions(+), 12 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 418dd4a92..c3b334315 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -36,6 +36,8 @@ class Result: Manipulate and read DADF5 files. DADF5 (DAMASK HDF5) files contain DAMASK results. + The group/folder structure reflects the input data + in material.yaml. """ def __init__(self,fname): @@ -1325,6 +1327,26 @@ class Result: def read(self,labels,compress=True,strip=True): + """ + Export data from file per phase/homogenization. + + The returned data structure reflects the group/folder structure + in the DADF5 file. + + Parameters + ---------- + labels : str or list of, optional + Labels of the datasets to be read. + compress : bool + Squeeze out dictionaries that are not needed for a unique + structure. This might be beneficial in the case of single + constituent or single phase simulations or if only one + time increment is considered. Defaults to 'True'. + strip : bool + Remove branches that contain no dataset. Defaults to + 'True'. + + """ r = {} labels_ = set([labels] if isinstance(labels,str) else labels) @@ -1357,6 +1379,30 @@ class Result: def place(self,labels,compress=True,strip=True,constituents=None,fill_float=0.0,fill_int=0): + """ + Export data from file suitable sorted for spatial operations. + + The returned data structure reflects the group/folder structure + in the DADF5 file. In the case of multi phase simulations, the + data is merged from the individual phases/homogenizations. + + In the cases of a single constituent and single phase simulation + this function is equivalent to `read`. + + Parameters + ---------- + labels : str or list of, optional + Labels of the datasets to be read. + compress : bool + Squeeze out dictionaries that are not needed for a unique + structure. This might be beneficial in the case of single + phase simulations or if only one time increment is + considered. Defaults to 'True'. + strip : bool + Remove branches that contain no dataset. Defaults to + 'True'. + + """ r = {} labels_ = set([labels] if isinstance(labels,str) else labels) @@ -1365,6 +1411,8 @@ class Result: else: constituents_ = constituents if isinstance(constituents,Iterable) else [constituents] + suffixes = [''] if self.N_constituents == 1 or len(constituents_) == 1 else \ + [f'#{c}' for c in constituents_] grp = 'mapping' if self.version_minor < 12 else 'cell_to' name = 'Name' if self.version_minor < 12 else 'label' @@ -1375,18 +1423,16 @@ class Result: at_cell_ph = [] in_data_ph = [] for c in constituents_: - at_cell_ph.append({label: np.where(f[os.path.join(grp,'phase')][:,c][name] == str.encode(label))[0] \ + at_cell_ph.append({label: np.where(f[os.path.join(grp,'phase')][:,c][name] == label.encode())[0] \ for label in self.visible['phases']}) in_data_ph.append({label: f[os.path.join(grp,'phase')][member][at_cell_ph[c][label]][...,0] \ for label in self.visible['phases']}) - at_cell_ho = {label: np.where(f[os.path.join(grp,'homogenization')][:][name] == str.encode(label))[0] \ + at_cell_ho = {label: np.where(f[os.path.join(grp,'homogenization')][:][name] == label.encode())[0] \ for label in self.visible['homogenizations']} - in_data_ho = {label: f[os.path.join(grp,'homogenization')][member][at_cell_ho[label]][...,0] \ + in_data_ho = {label: f[os.path.join(grp,'homogenization')][member][at_cell_ho[label]] \ for label in self.visible['homogenizations']} - c = 0 - for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{},'geometry':{}} @@ -1395,22 +1441,28 @@ class Result: for ph in self.visible['phases']: for me in f[os.path.join(inc,'phase',ph)].keys(): - if me not in r[inc]['phase'].keys(): r[inc]['phase'][me] = {} + if me not in r[inc]['phase'].keys(): + r[inc]['phase'][me] = {} + for la in labels_.intersection(f[os.path.join(inc,'phase',ph,me)].keys()): data = ma.array(_read(f,os.path.join(inc,'phase',ph,me,la))) - if la not in r[inc]['phase'][me].keys(): + if la+suffixes[0] not in r[inc]['phase'][me].keys(): container = np.empty((self.N_materialpoints,)+data.shape[1:],dtype=data.dtype) fill_value = fill_float if data.dtype in np.sctypes['float'] else \ fill_int - r[inc]['phase'][me][la] = \ - ma.array(container,fill_value=fill_value,mask=True) + for c,suffix in zip(constituents_, suffixes): + r[inc]['phase'][me][la+suffix] = \ + ma.array(container,fill_value=fill_value,mask=True) - r[inc]['phase'][me][la][at_cell_ph[c][ph]] = data[in_data_ph[c][ph]] + for c,suffix in zip(constituents_, suffixes): + r[inc]['phase'][me][la+suffix][at_cell_ph[c][ph]] = data[in_data_ph[c][ph]] for ho in self.visible['homogenizations']: for me in f[os.path.join(inc,'homogenization',ho)].keys(): - if me not in r[inc]['homogenization'].keys(): r[inc]['homogenization'][me] = {} + if me not in r[inc]['homogenization'].keys(): + r[inc]['homogenization'][me] = {} + for la in labels_.intersection(f[os.path.join(inc,'homogenization',ho,me)].keys()): data = ma.array(_read(f,os.path.join(inc,'homogenization',ho,me,la))) diff --git a/python/damask/util.py b/python/damask/util.py index a2cb94745..80d57d3dd 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -131,7 +131,7 @@ def show_progress(iterable,N_iter=None,prefix='',bar_length=50): Character length of bar. Defaults to 50. """ - if N_iter == 1 or len(iterable) == 1: + if N_iter == 1 or (hasattr(iterable,'__len__') and len(iterable) == 1): for item in iterable: yield item else: From 07c9cf5f1a9dbd2d3cb07afbd49902ef3dfcd4c1 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Wed, 31 Mar 2021 18:30:07 +0000 Subject: [PATCH 081/219] - improved reporting and slicing of table. - implemented numpy-like `allclose` and `isclose` --- python/damask/_table.py | 196 ++++++++++++++++++++++++---- python/damask/_test.py | 4 +- python/tests/test_ConfigMaterial.py | 9 +- python/tests/test_Grid.py | 3 +- python/tests/test_Table.py | 57 ++++---- 5 files changed, 212 insertions(+), 57 deletions(-) diff --git a/python/damask/_table.py b/python/damask/_table.py index ee64ba017..fb7e17ef8 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -27,20 +27,69 @@ class Table: self.comments = [] if comments_ is None else [c for c in comments_] self.data = pd.DataFrame(data=data) self.shapes = { k:(v,) if isinstance(v,(np.int64,np.int32,int)) else v for k,v in shapes.items() } - self._label_uniform() + self._relabel('uniform') + def __repr__(self): """Brief overview.""" - return '\n'.join(['# '+c for c in self.comments])+'\n'+self.data.__repr__() + self._relabel('shapes') + data_repr = self.data.__repr__() + self._relabel('uniform') + return '\n'.join(['# '+c for c in self.comments])+'\n'+data_repr + def __getitem__(self,item): - """Return slice according to item.""" - return self.__class__(data=self.data[item],shapes=self.shapes,comments=self.comments) + """ + Slice the Table according to item. + + Parameters + ---------- + item : row and/or column indexer + Slice to select from Table. + + Returns + ------- + slice : Table + Sliced part of the Table. + + Examples + -------- + >>> import damask + >>> import numpy as np + >>> tbl = damask.Table(data=np.arange(12).reshape((4,3)), + ... shapes=dict(colA=(1,),colB=(1,),colC=(1,))) + >>> tbl['colA','colB'] + colA colB + 0 0 1 + 1 3 4 + 2 6 7 + 3 9 10 + >>> tbl[::2,['colB','colA']] + colB colA + 0 1 0 + 2 7 6 + >>> tbl[1:2,'colB'] + colB + 1 4 + 2 7 + + """ + item = (item,slice(None,None,None)) if isinstance(item,slice) else \ + item if isinstance(item[0],slice) else \ + (slice(None,None,None),item) + sliced = self.data.loc[item] + cols = np.array(sliced.columns if isinstance(sliced,pd.core.frame.DataFrame) else [item[1]]) + _,idx = np.unique(cols,return_index=True) + return self.__class__(data=sliced, + shapes = {k:self.shapes[k] for k in cols[np.sort(idx)]}, + comments=self.comments) + def __len__(self): """Number of rows.""" return len(self.data) + def __copy__(self): """Create deep copy.""" return copy.deepcopy(self) @@ -48,21 +97,51 @@ class Table: copy = __copy__ - def _label_discrete(self): - """Label data individually, e.g. v v v ==> 1_v 2_v 3_v.""" + def _label(self,what,how): + """ + Expand labels according to data shape. + + Parameters + ---------- + what : str or list + Labels to expand. + how : str + Mode of labeling. + 'uniform' ==> v v v + 'shapes' ==> 3:v v v + 'linear' ==> 1_v 2_v 3_v + + """ + what = [what] if isinstance(what,str) else what labels = [] - for label,shape in self.shapes.items(): - size = int(np.prod(shape)) - labels += [('' if size == 1 else f'{i+1}_')+label for i in range(size)] - self.data.columns = labels + for label in what: + shape = self.shapes[label] + size = np.prod(shape,dtype=int) + if how == 'uniform': + labels += [label] * size + elif how == 'shapes': + labels += [('' if size == 1 or i>0 else f'{util.srepr(shape,"x")}:')+label for i in range(size)] + elif how == 'linear': + labels += [('' if size == 1 else f'{i+1}_')+label for i in range(size)] + else: + raise KeyError + return labels - def _label_uniform(self): - """Label data uniformly, e.g. 1_v 2_v 3_v ==> v v v.""" - labels = [] - for label,shape in self.shapes.items(): - labels += [label] * int(np.prod(shape)) - self.data.columns = labels + def _relabel(self,how): + """ + Modify labeling of data in-place. + + Parameters + ---------- + how : str + Mode of labeling. + 'uniform' ==> v v v + 'shapes' ==> 3:v v v + 'linear' ==> 1_v 2_v 3_v + + """ + self.data.columns = self._label(self.shapes,how) def _add_comment(self,label,shape,info): @@ -72,6 +151,62 @@ class Table: self.comments.append(f'{specific} / {general}') + def isclose(self,other,rtol=1e-5,atol=1e-8,equal_nan=True): + """ + Report where values are approximately equal to corresponding ones of other Table. + + Parameters + ---------- + other : Table + Table to compare against. + rtol : float, optional + Relative tolerance of equality. + atol : float, optional + Absolute tolerance of equality. + equal_nan : bool, optional + Consider matching NaN values as equal. Defaults to True. + + Returns + ------- + mask : numpy.ndarray bool + Mask indicating where corresponding table values are close. + + """ + return np.isclose( self.data.to_numpy(), + other.data.to_numpy(), + rtol=rtol, + atol=atol, + equal_nan=equal_nan) + + + def allclose(self,other,rtol=1e-5,atol=1e-8,equal_nan=True): + """ + Test whether all values are approximately equal to corresponding ones of other Table. + + Parameters + ---------- + other : Table + Table to compare against. + rtol : float, optional + Relative tolerance of equality. + atol : float, optional + Absolute tolerance of equality. + equal_nan : bool, optional + Consider matching NaN values as equal. Defaults to True. + + Returns + ------- + answer : bool + Whether corresponding values are close between both tables. + + """ + return np.allclose( self.data.to_numpy(), + other.data.to_numpy(), + rtol=rtol, + atol=atol, + equal_nan=equal_nan) + + @staticmethod def load(fname): """ @@ -130,12 +265,13 @@ class Table: return Table(data,shapes,comments) + @staticmethod def load_ang(fname): """ Load from ang file. - A valid TSL ang file needs to contains the following columns: + A valid TSL ang file has to have the following columns: * Euler angles (Bunge notation) in radians, 3 floats, label 'eu'. * Spatial position in meters, 2 floats, label 'pos'. * Image quality, 1 float, label 'IQ'. @@ -225,10 +361,12 @@ class Table: """ dup = self.copy() dup._add_comment(label,data.shape[1:],info) - - if re.match(r'[0-9]*?_',label): - idx,key = label.split('_',1) - iloc = dup.data.columns.get_loc(key).tolist().index(True) + int(idx) -1 + m = re.match(r'(.*)\[((\d+,)*(\d+))\]',label) + if m: + key = m.group(1) + idx = np.ravel_multi_index(tuple(map(int,m.group(2).split(","))), + self.shapes[key]) + iloc = dup.data.columns.get_loc(key).tolist().index(True) + idx dup.data.iloc[:,iloc] = data else: dup.data[label] = data.reshape(dup.data[label].shape) @@ -331,10 +469,18 @@ class Table: Updated table. """ + labels_ = [labels] if isinstance(labels,str) else labels.copy() + for i,l in enumerate(labels_): + m = re.match(r'(.*)\[((\d+,)*(\d+))\]',l) + if m: + idx = np.ravel_multi_index(tuple(map(int,m.group(2).split(','))), + self.shapes[m.group(1)]) + labels_[i] = f'{1+idx}_{m.group(1)}' + dup = self.copy() - dup._label_discrete() - dup.data.sort_values(labels,axis=0,inplace=True,ascending=ascending) - dup._label_uniform() + dup._relabel('linear') + dup.data.sort_values(labels_,axis=0,inplace=True,ascending=ascending) + dup._relabel('uniform') dup.comments.append(f'sorted {"ascending" if ascending else "descending"} by {labels}') return dup @@ -399,7 +545,7 @@ class Table: ---------- fname : file, str, or pathlib.Path Filename or file for writing. - legacy : Boolean, optional + legacy : bool, optional Write table in legacy style, indicating header lines by "N header" in contrast to using comment sign ('#') at beginning of lines. diff --git a/python/damask/_test.py b/python/damask/_test.py index f8fb24cca..455a92520 100644 --- a/python/damask/_test.py +++ b/python/damask/_test.py @@ -399,7 +399,7 @@ class Test: tables = [damask.Table.load(filename) for filename in files] for table in tables: - table._label_discrete() + table._relabel('linear') columns += [columns[0]]*(len(files)-len(columns)) # extend to same length as files columns = columns[:len(files)] # truncate to same length as files @@ -419,7 +419,7 @@ class Test: data = [] for table,labels in zip(tables,columns): - table._label_uniform() + table._relabel('uniform') data.append(np.hstack(list(table.get(label) for label in labels))) diff --git a/python/tests/test_ConfigMaterial.py b/python/tests/test_ConfigMaterial.py index 5ac0e546a..cf4a8ab9d 100644 --- a/python/tests/test_ConfigMaterial.py +++ b/python/tests/test_ConfigMaterial.py @@ -86,9 +86,12 @@ class TestConfigMaterial: def test_from_table(self): N = np.random.randint(3,10) - a = np.vstack((np.hstack((np.arange(N),np.arange(N)[::-1])),np.ones(N*2),np.zeros(N*2),np.ones(N*2),np.ones(N*2))).T - t = Table(a,{'varying':1,'constant':4}) - c = ConfigMaterial.from_table(t,**{'phase':'varying','O':'constant','homogenization':'4_constant'}) + a = np.vstack((np.hstack((np.arange(N),np.arange(N)[::-1])), + np.ones(N*2),np.zeros(N*2),np.ones(N*2),np.ones(N*2), + np.ones(N*2), + )).T + t = Table(a,{'varying':1,'constant':4,'ones':1}) + c = ConfigMaterial.from_table(t,**{'phase':'varying','O':'constant','homogenization':'ones'}) assert len(c['material']) == N for i,m in enumerate(c['material']): assert m['homogenization'] == 1 and (m['constituents'][0]['O'] == [1,0,1,1]).all() diff --git a/python/tests/test_Grid.py b/python/tests/test_Grid.py index 7e94686ee..018ff8a30 100644 --- a/python/tests/test_Grid.py +++ b/python/tests/test_Grid.py @@ -407,7 +407,8 @@ class TestGrid: z=np.ones(cells.prod()) z[cells[:2].prod()*int(cells[2]/2):]=0 t = Table(np.column_stack((coords,z)),{'coords':3,'z':1}) - g = Grid.from_table(t,'coords',['1_coords','z']) + t = t.add('indicator',t.get('coords')[:,0]) + g = Grid.from_table(t,'coords',['indicator','z']) assert g.N_materials == g.cells[0]*2 and (g.material[:,:,-1]-g.material[:,:,0] == cells[0]).all() diff --git a/python/tests/test_Table.py b/python/tests/test_Table.py index 8f617aff5..286c176e6 100644 --- a/python/tests/test_Table.py +++ b/python/tests/test_Table.py @@ -36,13 +36,33 @@ class TestTable: d = default.get('F') assert np.allclose(d,1.0) and d.shape[1:] == (3,3) - def test_get_component(self,default): - d = default.get('5_F') - assert np.allclose(d,1.0) and d.shape[1:] == (1,) + def test_set(self,default): + d = default.set('F',np.zeros((5,3,3)),'set to zero').get('F') + assert np.allclose(d,0.0) and d.shape[1:] == (3,3) - @pytest.mark.parametrize('N',[10,40]) - def test_getitem(self,N): - assert len(Table(np.random.rand(N,1),{'X':1})[:N//2]) == N//2 + def test_set_component(self,default): + d = default.set('F[0,0]',np.zeros((5)),'set to zero').get('F') + assert np.allclose(d[...,0,0],0.0) and d.shape[1:] == (3,3) + + def test_labels(self,default): + assert default.labels == ['F','v','s'] + + def test_add(self,default): + d = np.random.random((5,9)) + assert np.allclose(d,default.add('nine',d,'random data').get('nine')) + + def test_isclose(self,default): + assert default.isclose(default).all() + + def test_allclose(self,default): + assert default.allclose(default) + + @pytest.mark.parametrize('N',[1,3,4]) + def test_slice(self,default,N): + assert len(default[:N]) == 1+N + assert len(default[:N,['F','s']]) == 1+N + assert default[N:].get('F').shape == (len(default)-N,3,3) + assert (default[:N,['v','s']].data == default['v','s'][:N].data).all().all() @pytest.mark.parametrize('mode',['str','path']) def test_write_read(self,default,tmp_path,mode): @@ -91,21 +111,6 @@ class TestTable: with open(ref_path/fname) as f: Table.load(f) - def test_set(self,default): - d = default.set('F',np.zeros((5,3,3)),'set to zero').get('F') - assert np.allclose(d,0.0) and d.shape[1:] == (3,3) - - def test_set_component(self,default): - d = default.set('1_F',np.zeros((5)),'set to zero').get('F') - assert np.allclose(d[...,0,0],0.0) and d.shape[1:] == (3,3) - - def test_labels(self,default): - assert default.labels == ['F','v','s'] - - def test_add(self,default): - d = np.random.random((5,9)) - assert np.allclose(d,default.add('nine',d,'random data').get('nine')) - def test_rename_equivalent(self): x = np.random.random((5,13)) t = Table(x,{'F':(3,3),'v':(3,),'s':(1,)},['random test data']) @@ -176,15 +181,15 @@ class TestTable: def test_sort_component(self): x = np.random.random((5,12)) t = Table(x,{'F':(3,3),'v':(3,)},['random test data']) - unsort = t.get('4_F') - sort = t.sort_by('4_F').get('4_F') + unsort = t.get('F')[:,1,0] + sort = t.sort_by('F[1,0]').get('F')[:,1,0] assert np.all(np.sort(unsort,0)==sort) def test_sort_revert(self): x = np.random.random((5,12)) t = Table(x,{'F':(3,3),'v':(3,)},['random test data']) - sort = t.sort_by('4_F',ascending=False).get('4_F') - assert np.all(np.sort(sort,0)==sort[::-1,:]) + sort = t.sort_by('F[1,0]',ascending=False).get('F')[:,1,0] + assert np.all(np.sort(sort,0)==sort[::-1]) def test_sort(self): t = Table(np.array([[0,1,],[2,1,]]), @@ -192,4 +197,4 @@ class TestTable: ['test data'])\ .add('s',np.array(['b','a']))\ .sort_by('s') - assert np.all(t.get('1_v') == np.array([2,0]).reshape(2,1)) + assert np.all(t.get('v')[:,0] == np.array([2,0])) From c1176141ef48d20fe3ebfc89531094066db0abca Mon Sep 17 00:00:00 2001 From: Test User Date: Thu, 1 Apr 2021 00:01:17 +0200 Subject: [PATCH 082/219] [skip ci] updated version information after successful test of v3.0.0-alpha2-673-g0c08c9753 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 445e4606c..0c9d33075 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-670-ge6143f6ee +v3.0.0-alpha2-673-g0c08c9753 From c1f7ea750b03999106c67dba4306d0a09b148bfa Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 1 Apr 2021 00:13:07 +0200 Subject: [PATCH 083/219] legacy access not needed anymore --- PRIVATE | 2 +- python/damask/_table.py | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/PRIVATE b/PRIVATE index 4511a963d..f1ac733d5 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 4511a963da5094db309a6a68783f24a23c76da81 +Subproject commit f1ac733d5eb90de1cdcaf79a261157c9034f8136 diff --git a/python/damask/_table.py b/python/damask/_table.py index e010bdd22..e5f436f75 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -322,11 +322,7 @@ class Table: Array of column data. """ - if re.match(r'[0-9]*?_',label): - idx,key = label.split('_',1) - data = self.data[key].to_numpy()[:,int(idx)-1].reshape(-1,1) - else: - data = self.data[label].to_numpy().reshape((-1,)+self.shapes[label]) + data = self.data[label].to_numpy().reshape((-1,)+self.shapes[label]) return data.astype(type(data.flatten()[0])) From 2397df88f96afa37ec8f22a69f6785d19fc3a64d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 1 Apr 2021 00:02:51 +0200 Subject: [PATCH 084/219] documenting --- python/damask/_result.py | 62 +++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index c3b334315..7b26357cd 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1359,19 +1359,19 @@ class Result: for ph in self.visible['phases']: r[inc]['phase'][ph] = {} - for me in f[os.path.join(inc,'phase',ph)].keys(): - r[inc]['phase'][ph][me] = {} - for la in labels_.intersection(f[os.path.join(inc,'phase',ph,me)].keys()): - r[inc]['phase'][ph][me][la] = \ - _read(f,os.path.join(inc,'phase',ph,me,la)) + for field in f[os.path.join(inc,'phase',ph)].keys(): + r[inc]['phase'][ph][field] = {} + for la in labels_.intersection(f[os.path.join(inc,'phase',ph,field)].keys()): + r[inc]['phase'][ph][field][la] = \ + _read(f,os.path.join(inc,'phase',ph,field,la)) for ho in self.visible['homogenizations']: r[inc]['homogenization'][ho] = {} - for me in f[os.path.join(inc,'homogenization',ho)].keys(): - r[inc]['homogenization'][ho][me] = {} - for la in labels_.intersection(f[os.path.join(inc,'homogenization',ho,me)].keys()): - r[inc]['homogenization'][ho][me][la] = \ - _read(f,os.path.join(inc,'homogenization',ho,me,la)) + for field in f[os.path.join(inc,'homogenization',ho)].keys(): + r[inc]['homogenization'][ho][field] = {} + for la in labels_.intersection(f[os.path.join(inc,'homogenization',ho,field)].keys()): + r[inc]['homogenization'][ho][field][la] = \ + _read(f,os.path.join(inc,'homogenization',ho,field,la)) if strip: r = util.dict_strip(r) if compress: r = util.dict_compress(r) @@ -1401,7 +1401,15 @@ class Result: strip : bool Remove branches that contain no dataset. Defaults to 'True'. - + constituents : int or list of, optional + Constituents to consider. Defaults to 'None', in which case + all constituents are considered. + fill_float : float + Fill value for non existent entries of floating point type. + Defaults to 0.0. + fill_int : int + Fill value for non existent entries of integer type. + Defaults to 0. """ r = {} @@ -1440,40 +1448,40 @@ class Result: r[inc]['geometry'][la] = _read(f,os.path.join(inc,'geometry',la)) for ph in self.visible['phases']: - for me in f[os.path.join(inc,'phase',ph)].keys(): - if me not in r[inc]['phase'].keys(): - r[inc]['phase'][me] = {} + for field in f[os.path.join(inc,'phase',ph)].keys(): + if field not in r[inc]['phase'].keys(): + r[inc]['phase'][field] = {} - for la in labels_.intersection(f[os.path.join(inc,'phase',ph,me)].keys()): - data = ma.array(_read(f,os.path.join(inc,'phase',ph,me,la))) + for la in labels_.intersection(f[os.path.join(inc,'phase',ph,field)].keys()): + data = ma.array(_read(f,os.path.join(inc,'phase',ph,field,la))) - if la+suffixes[0] not in r[inc]['phase'][me].keys(): + if la+suffixes[0] not in r[inc]['phase'][field].keys(): container = np.empty((self.N_materialpoints,)+data.shape[1:],dtype=data.dtype) fill_value = fill_float if data.dtype in np.sctypes['float'] else \ fill_int for c,suffix in zip(constituents_, suffixes): - r[inc]['phase'][me][la+suffix] = \ + r[inc]['phase'][field][la+suffix] = \ ma.array(container,fill_value=fill_value,mask=True) for c,suffix in zip(constituents_, suffixes): - r[inc]['phase'][me][la+suffix][at_cell_ph[c][ph]] = data[in_data_ph[c][ph]] + r[inc]['phase'][field][la+suffix][at_cell_ph[c][ph]] = data[in_data_ph[c][ph]] for ho in self.visible['homogenizations']: - for me in f[os.path.join(inc,'homogenization',ho)].keys(): - if me not in r[inc]['homogenization'].keys(): - r[inc]['homogenization'][me] = {} + for field in f[os.path.join(inc,'homogenization',ho)].keys(): + if field not in r[inc]['homogenization'].keys(): + r[inc]['homogenization'][field] = {} - for la in labels_.intersection(f[os.path.join(inc,'homogenization',ho,me)].keys()): - data = ma.array(_read(f,os.path.join(inc,'homogenization',ho,me,la))) + for la in labels_.intersection(f[os.path.join(inc,'homogenization',ho,field)].keys()): + data = ma.array(_read(f,os.path.join(inc,'homogenization',ho,field,la))) - if la not in r[inc]['homogenization'][me].keys(): + if la not in r[inc]['homogenization'][field].keys(): container = np.empty((self.N_materialpoints,)+data.shape[1:],dtype=data.dtype) fill_value = fill_float if data.dtype in np.sctypes['float'] else \ fill_int - r[inc]['homogenization'][me][la] = \ + r[inc]['homogenization'][field][la] = \ ma.array(container,fill_value=fill_value,mask=True) - r[inc]['homogenization'][me][la][at_cell_ho[ho]] = data[in_data_ho[ho]] + r[inc]['homogenization'][field][la][at_cell_ho[ho]] = data[in_data_ho[ho]] if strip: r = util.dict_strip(r) if compress: r = util.dict_compress(r) From 85aaaa96f31cfc1813aad65ab6c9fbbbd9581478 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 1 Apr 2021 10:47:45 +0200 Subject: [PATCH 085/219] new tests --- ...d.material_yaml => measured.material.yaml} | 0 ...sionY.yaml => 12grains6x7x8.material.yaml} | 0 .../Result/4grains2x4x3.material.yaml | 678 ++++++++++++++++++ .../tests/reference/Result/4grains2x4x3.vtr | 30 + .../Result/4grains2x4x3_compressionY.hdf5 | Bin 0 -> 781336 bytes ...> 6grains6x7x8_single_phase.material.yaml} | 0 .../tests/reference/Result/compressionY.yaml | 17 + python/tests/test_ConfigMaterial.py | 4 +- 8 files changed, 727 insertions(+), 2 deletions(-) rename python/tests/reference/ConfigMaterial/{measured.material_yaml => measured.material.yaml} (100%) rename python/tests/reference/Result/{12grains6x7x8_tensionY.yaml => 12grains6x7x8.material.yaml} (100%) create mode 100644 python/tests/reference/Result/4grains2x4x3.material.yaml create mode 100644 python/tests/reference/Result/4grains2x4x3.vtr create mode 100644 python/tests/reference/Result/4grains2x4x3_compressionY.hdf5 rename python/tests/reference/Result/{6grains6x7x8_single_phase_tensionY.yaml => 6grains6x7x8_single_phase.material.yaml} (100%) create mode 100644 python/tests/reference/Result/compressionY.yaml diff --git a/python/tests/reference/ConfigMaterial/measured.material_yaml b/python/tests/reference/ConfigMaterial/measured.material.yaml similarity index 100% rename from python/tests/reference/ConfigMaterial/measured.material_yaml rename to python/tests/reference/ConfigMaterial/measured.material.yaml diff --git a/python/tests/reference/Result/12grains6x7x8_tensionY.yaml b/python/tests/reference/Result/12grains6x7x8.material.yaml similarity index 100% rename from python/tests/reference/Result/12grains6x7x8_tensionY.yaml rename to python/tests/reference/Result/12grains6x7x8.material.yaml diff --git a/python/tests/reference/Result/4grains2x4x3.material.yaml b/python/tests/reference/Result/4grains2x4x3.material.yaml new file mode 100644 index 000000000..4cff681c0 --- /dev/null +++ b/python/tests/reference/Result/4grains2x4x3.material.yaml @@ -0,0 +1,678 @@ +material: + - constituents: + - phase: A + O: [0.44698096036898677, -0.035696623617731814, 0.050331402131209624, -0.8924127532086364] + v: 0.125 + - phase: A + O: [0.6226205515354057, 0.4257792272120092, -0.6365250917893261, 0.16090837766592916] + v: 0.125 + - phase: A + O: [0.4319357791504236, 0.5804552577310466, 0.4870786336250474, 0.48913963356904305] + v: 0.125 + - phase: A + O: [0.6712122425649047, -0.5315470950319967, 0.11982471915778993, -0.5025672570639611] + v: 0.125 + - phase: A + O: [0.03979536866120591, -0.01919843067074171, -0.5618628311727827, 0.8260495795286167] + v: 0.125 + - phase: A + O: [0.6951890945163803, -0.46325436790720337, 0.03393768848173515, -0.5485943371753935] + v: 0.125 + - phase: A + O: [0.3489469292795834, -0.5959323325634578, -0.6067706771532161, 0.3936115355256417] + v: 0.125 + - phase: A + O: [0.39500485674202723, -0.07573446369604235, -0.015761384830863343, -0.9154163167144754] + v: 0.125 + homogenization: RGC + - constituents: + - phase: B + O: [0.9221278604171202, 0.32701451341562027, 0.15952215192749652, -0.1315081750406033] + v: 0.125 + - phase: B + O: [0.8117843306311869, 0.4102779561929707, -0.18584663447455768, 0.37167085930736465] + v: 0.125 + - phase: B + O: [0.6548302235705483, 0.6510678661349768, -0.3832730015357094, 0.02024396894884073] + v: 0.125 + - phase: B + O: [0.04255709858343937, -0.3005730931619659, -0.3060125731417352, -0.9023308783957146] + v: 0.125 + - phase: B + O: [0.6960740097259569, 0.16329320418261428, 0.6991228405747408, 0.006599715032396515] + v: 0.125 + - phase: B + O: [0.48818278044780217, -0.664294296073913, 0.2679908412891581, 0.4985695238008905] + v: 0.125 + - phase: B + O: [0.545426202615872, 0.179298582176746, -0.7847831868864313, -0.23340442478628137] + v: 0.125 + - phase: B + O: [0.8566603715426528, 0.26967937521434965, -0.03159131558814077, 0.43864339866435076] + v: 0.125 + homogenization: RGC + - constituents: + - phase: C + O: [0.140304599816322, -0.017971728003341014, -0.9895572782263894, 0.027713342853867628] + v: 0.125 + - phase: C + O: [0.8096406385129331, 0.2395956967578664, -0.25531574170054405, -0.47105181307727034] + v: 0.125 + - phase: C + O: [0.15570676199790476, -0.7501738841096782, 0.2328253832435299, -0.5989882209070811] + v: 0.125 + - phase: C + O: [0.4595649941522109, 0.3331746723324176, 0.23957383093695328, 0.7876541331042811] + v: 0.125 + - phase: C + O: [0.2969510261483044, 0.0027640644222379847, -0.8133130954773664, 0.5003341450894221] + v: 0.125 + - phase: C + O: [0.114170281047612, -0.9068850613039258, 0.3701597984948465, -0.16585040273553361] + v: 0.125 + - phase: C + O: [0.29658840046433166, -0.5331902828876833, 0.7365409179409275, 0.2919776004129383] + v: 0.125 + - phase: C + O: [0.931315147629592, -0.2017743466108175, 0.30303719188324046, 0.010376376100021569] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.20901169650798976, 0.5778057521557359, -0.3628020593274987, 0.7005920990464581] + v: 0.125 + - phase: B + O: [0.6025573623737024, 0.7345291803280383, 0.3086529661391562, 0.04609614722911203] + v: 0.125 + - phase: C + O: [0.6402291970447783, -0.5402560454335561, -0.5285008279381848, -0.13753856002062462] + v: 0.125 + - phase: A + O: [0.12506307996119548, 0.5336909245447153, 0.8344001590799459, 0.05752910234470594] + v: 0.125 + - phase: B + O: [0.5504712846116686, -0.6241210958640075, 0.42061504390637533, 0.3612993320712448] + v: 0.125 + - phase: C + O: [0.3135636745691277, 0.6574027353927014, 0.6044800436379738, -0.32265049563317466] + v: 0.125 + - phase: A + O: [0.1619452502554878, -0.4269267792831907, -0.8080415555188633, 0.3722581169097929] + v: 0.125 + - phase: A + O: [0.17044595054343245, 0.8646695166660998, -0.30004868613437863, -0.365055599656809] + v: 0.125 + homogenization: RGC + - constituents: + - phase: B + O: [0.43255174377606787, 0.2026672781261794, 0.35000490906160386, 0.8058048938583007] + v: 0.125 + - phase: B + O: [0.19591912697365416, -0.8181375036268687, 0.3260880890153691, -0.4311998133665892] + v: 0.125 + - phase: A + O: [0.1373248436058589, -0.43524771427953446, -0.8885320171891298, -0.047033700395389226] + v: 0.125 + - phase: A + O: [0.250519065956112, -0.7636612069861932, 0.5672425862778043, -0.17971534951065127] + v: 0.125 + - phase: B + O: [0.600521695167639, -0.2273230963128902, 0.7563911883237204, -0.12478090295368073] + v: 0.125 + - phase: A + O: [0.4281846857945264, 0.5284504248063085, 0.21428541450090705, 0.7010561921167584] + v: 0.125 + - phase: A + O: [0.34007599923699156, 0.5500172687924186, 0.6138467460818403, -0.45279298923219496] + v: 0.125 + - phase: A + O: [0.8581382626679844, -0.20034169756111123, 0.3134907520728513, -0.35381559424127107] + v: 0.125 + homogenization: RGC + - constituents: + - phase: C + O: [0.18637512817696594, 0.9354389080016575, 0.2967480269088709, -0.04646471262558266] + v: 0.125 + - phase: C + O: [0.33425800495572805, 0.24948308477875414, 0.7297193930640264, 0.5417927499686225] + v: 0.125 + - phase: A + O: [0.11918214701666907, -0.4185869380028542, 0.618905484805619, -0.6538628235673086] + v: 0.125 + - phase: A + O: [0.40732205687168244, -0.6166051531766635, -0.6737097202702335, -0.0014282419993970551] + v: 0.125 + - phase: A + O: [0.68397144415648, 0.6848389352552103, 0.24111983008651763, 0.07099242125789083] + v: 0.125 + - phase: C + O: [0.05719438496521803, 0.2575447319897859, 0.5020591650211859, -0.8236116245968056] + v: 0.125 + - phase: A + O: [0.10565206937493385, -0.1109750475948143, 0.8781814355546643, 0.45312199824690885] + v: 0.125 + - phase: A + O: [0.22821192086563635, -0.9595048060506683, -0.07745760541549483, -0.1458429487626446] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.5745354940858776, 0.6366614824775295, 0.3307586622977252, -0.39391601907009377] + v: 0.125 + - phase: B + O: [0.3505113084912295, -0.6046500894621007, 0.6274019946374426, -0.34337563841687757] + v: 0.125 + - phase: A + O: [0.030949493058962222, 0.4416700940450431, 0.8819578143863066, 0.16161704906526728] + v: 0.125 + - phase: A + O: [0.13563849174261922, 0.2687388407244776, 0.809782239640578, -0.5036212459840637] + v: 0.125 + - phase: A + O: [0.2305505587522992, -0.6837828098041563, 0.3813348695443346, 0.577815910255975] + v: 0.125 + - phase: A + O: [0.10699977862890839, 0.8478562366641894, 0.26664808851893185, -0.4456339823355066] + v: 0.125 + - phase: A + O: [0.9203073703838264, 0.35592932457392046, 0.15147737103605818, -0.058337517855697775] + v: 0.125 + - phase: B + O: [0.8544895693446002, 0.43485422381677186, -0.2696115267291114, 0.08977195867747481] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.22196756947117874, 0.940293527559, -0.2573416285961528, -0.018808676859083388] + v: 0.125 + - phase: A + O: [0.28669138183611736, -0.5847463393505065, 0.6896415010701208, 0.3166612862331461] + v: 0.125 + - phase: A + O: [0.18214681844078473, 0.07037956730772883, 0.6195004937983107, -0.7603212421214639] + v: 0.125 + - phase: A + O: [0.5744613003376511, 0.17468957401795682, -0.7944671360487727, 0.09110289173380101] + v: 0.125 + - phase: C + O: [0.4329446256398051, -0.7351014072423584, 0.5116672951703971, -0.10188940697110307] + v: 0.125 + - phase: C + O: [0.2946245183318559, -0.8241105780568372, 0.40376354741611825, -0.2664829189845001] + v: 0.125 + - phase: A + O: [0.22212591383189398, -0.06959072743195248, -0.8166434230649855, -0.5281199945320578] + v: 0.125 + - phase: A + O: [0.038576201076459135, 0.9876698316278196, 0.06851090552108202, -0.13537516843004982] + v: 0.125 + homogenization: RGC + - constituents: + - phase: C + O: [0.004892880719601024, -0.02167422880443418, 0.3339942463386166, 0.9423131809205983] + v: 0.125 + - phase: A + O: [0.3719521264362446, -0.4055315244649798, -0.39177426332273346, 0.7373660725193388] + v: 0.125 + - phase: A + O: [0.010947854228877327, 0.16142752376310676, -0.19859031041582603, -0.9666349816080735] + v: 0.125 + - phase: B + O: [0.9101129345691923, -0.17592965401443023, -0.30944622338368544, 0.21209959453471436] + v: 0.125 + - phase: A + O: [0.5280075626141939, -0.4828698476824812, -0.1580687189774305, 0.6804843893155447] + v: 0.125 + - phase: A + O: [0.8213575048478461, 0.18229514326534527, -0.35486977770450967, -0.4076858727549186] + v: 0.125 + - phase: A + O: [0.16635046542653203, -0.8410358537737095, -0.47641083611371204, 0.19498443669415633] + v: 0.125 + - phase: B + O: [0.5406080589325533, 0.5405688205487984, -0.4980750162732086, -0.4092060056158767] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.41778322805525603, 0.23584193505422144, 0.8768801833720732, -0.03028035724639885] + v: 0.125 + - phase: A + O: [0.8727428843707065, 0.0764211249039828, 0.3927224252414984, -0.2797298092108618] + v: 0.125 + - phase: A + O: [0.8766166377340643, -0.2644877070285106, 0.022928146762306964, -0.40132757613285325] + v: 0.125 + - phase: A + O: [0.6643649540361558, -0.04353445577200276, -0.2630693201131682, -0.6982252443333509] + v: 0.125 + - phase: A + O: [0.43011162904952843, -0.7133156350005553, 0.22368449997894274, -0.5061126711408104] + v: 0.125 + - phase: A + O: [0.42119993016818996, -0.2666762728079305, 0.7798784815692744, 0.37850223028772895] + v: 0.125 + - phase: A + O: [0.17194138099812353, 0.48707029434265314, 0.28918455812138427, -0.8059596647559721] + v: 0.125 + - phase: A + O: [0.7411029340880614, -0.6424443807902435, 0.06269338980849715, 0.18466509565000905] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.2238963963710994, -0.0650586111271435, -0.4249089470195672, -0.8746943280672199] + v: 0.125 + - phase: A + O: [0.11834025356863993, -0.8856449810417544, 0.417012782917471, 0.16651994122112387] + v: 0.125 + - phase: A + O: [0.11716309944373668, 0.0038756181092136927, -0.7000966032560261, -0.7043596622623864] + v: 0.125 + - phase: A + O: [0.45702665319142677, -0.16783958203387148, -0.15365667123574342, 0.8598523945190182] + v: 0.125 + - phase: A + O: [0.5197700015250588, 0.41758011415389684, -0.06820554688133636, 0.7421684425738383] + v: 0.125 + - phase: A + O: [0.675852597832269, -0.5552996378928718, 0.4213174293100185, 0.23949363648960756] + v: 0.125 + - phase: A + O: [0.5936583232008587, 0.6945289973655595, -0.40553899121228437, -0.027154994370431035] + v: 0.125 + - phase: A + O: [0.1865986177378815, 0.3352356341235895, 0.35399611880081633, -0.8529271793922534] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.04264635665959766, -0.25662858077651657, 0.9118921459098731, -0.3174520027030545] + v: 0.125 + - phase: A + O: [0.8821155978581948, 0.3761807268996467, 0.1631361963837017, 0.23183337584133834] + v: 0.125 + - phase: A + O: [0.162154410316598, -0.8783087060961443, 0.0990284993753847, -0.4387175860642615] + v: 0.125 + - phase: A + O: [0.5420568096555354, 0.5088379086577298, 0.34515629818391275, -0.572822422433749] + v: 0.125 + - phase: A + O: [0.4535105167294993, -0.351824950997862, 0.5869707747562448, -0.5709752399650516] + v: 0.125 + - phase: A + O: [0.8098666527705685, 0.36698878904202453, -0.4428476393801139, 0.11541751055678014] + v: 0.125 + - phase: A + O: [0.2576165318782538, 0.537377864604212, -0.6660199792713344, 0.44863809506978913] + v: 0.125 + - phase: A + O: [0.665871020774723, -0.24779933206030424, -0.6964987066828571, 0.10050286718299539] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.5998961636312351, -0.5496518322385892, 0.10155928244475286, 0.5724449041843198] + v: 0.125 + - phase: A + O: [0.7039639404137236, 0.03679879173607231, 0.58207433274894, 0.4053024681380869] + v: 0.125 + - phase: A + O: [0.40054268633071116, 0.37951399049616763, 0.5867236594596857, -0.5926972539795397] + v: 0.125 + - phase: A + O: [0.9355573844663049, 0.24834752099784146, 0.19019564545030732, 0.16395580391231754] + v: 0.125 + - phase: A + O: [0.7776851244299001, 0.5132289287723679, -0.3500697782737797, 0.0961928492714775] + v: 0.125 + - phase: A + O: [0.14184146561701433, -0.12106060201428649, 0.06736696083733706, 0.9801464287845448] + v: 0.125 + - phase: A + O: [0.35378845612452303, 0.6454299208817863, -0.6758747727133072, 0.03804257027716481] + v: 0.125 + - phase: A + O: [0.5450137677982273, -0.6067354536251314, -0.5773779505037945, 0.03829862264786783] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.8960165930555501, 0.24799888375444512, -0.3529216677489853, 0.10534284531447227] + v: 0.125 + - phase: A + O: [0.018356029815615817, -0.2889337455527527, 0.9520448827103584, 0.09894891689798985] + v: 0.125 + - phase: A + O: [0.853080700130541, -0.3850382673796441, 0.3507108308253732, 0.03163486778610022] + v: 0.125 + - phase: A + O: [0.3115000788768896, -0.36279737244767013, 0.6484519555216468, -0.5923308440263011] + v: 0.125 + - phase: A + O: [0.44453200197416054, 0.5366087739174971, -0.4155131463908387, -0.5846290688564767] + v: 0.125 + - phase: A + O: [0.6294708415113138, -0.5730458394479108, 0.3971797612768184, -0.34297691294104227] + v: 0.125 + - phase: A + O: [0.7012827551365688, -0.6926674077585473, -0.1570646347205316, -0.06119689614043776] + v: 0.125 + - phase: A + O: [0.344127722728084, -0.02877253391263471, -0.12761292039202274, 0.9297651285627186] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.6978484686818835, 0.22305447962726752, 0.026182556001199425, -0.6801240237175888] + v: 0.125 + - phase: A + O: [0.9628977633574072, 0.16069766981498335, 0.2167078702347067, -0.006469560701840579] + v: 0.125 + - phase: A + O: [0.5032342094162214, -0.32097872787787546, 0.8022984104181043, -0.006726616067118365] + v: 0.125 + - phase: A + O: [0.8004358150893949, 0.0875805156227694, -0.3568768378095974, -0.47357267851983204] + v: 0.125 + - phase: A + O: [0.5880748138588325, 0.45495016865260346, 0.5556078663040557, -0.37214010298397254] + v: 0.125 + - phase: A + O: [0.0242946564098417, 0.6005127022483121, 0.7620365834257689, -0.24102802664656872] + v: 0.125 + - phase: A + O: [0.34550850696510604, 0.7299878005482168, -0.29949045445085315, -0.5079834154363129] + v: 0.125 + - phase: A + O: [0.10265979489126274, 0.34339772969920185, 0.0799881993576351, 0.9301294822302113] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.5849010547063512, -0.46890126598541493, -0.141130615667434, -0.6466100125129551] + v: 0.125 + - phase: A + O: [0.3232591731614976, -0.2858051445366468, 0.8855713416105193, -0.17199513144701628] + v: 0.125 + - phase: A + O: [0.7530648506011821, -0.3316323026169325, -0.30797159948874325, -0.477563441396382] + v: 0.125 + - phase: A + O: [0.5841938587340145, -0.5195581188838846, 0.45610755437383976, 0.4251385601923404] + v: 0.125 + - phase: A + O: [0.5699287377636442, -0.7161652717835199, -0.40080048103879345, -0.04058955236816678] + v: 0.125 + - phase: A + O: [0.05536551119448681, -0.40478746018638956, -0.6031583160532334, -0.6850414717532457] + v: 0.125 + - phase: A + O: [0.2227977302479141, -0.48882932798587353, -0.15904170725500447, -0.8283192590122909] + v: 0.125 + - phase: A + O: [0.05275211816268626, -0.223660120175789, 0.6943402501868806, 0.6819713935662708] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.7102673449281939, 0.43290229875199215, 0.4268837400347354, 0.35480441225815024] + v: 0.125 + - phase: A + O: [0.2541648349387051, 0.3725842249682419, -0.13402399303768983, -0.8823937903655196] + v: 0.125 + - phase: A + O: [0.4091596391203177, 0.10748924891263324, 0.2807193957630742, -0.8615283349522196] + v: 0.125 + - phase: A + O: [0.16364908456142396, -0.9217193970202214, 0.11860582627366922, 0.33103623404821947] + v: 0.125 + - phase: A + O: [0.80868984786943, -0.5530964468638372, 0.18400280484186798, -0.07904440669549186] + v: 0.125 + - phase: A + O: [0.785539568992473, -0.42139749663876175, 0.03451711851851934, 0.45184101618034067] + v: 0.125 + - phase: A + O: [0.07920711616878613, -0.6177377682037178, -0.7622215143727179, 0.1764784562213612] + v: 0.125 + - phase: A + O: [0.6079704911212058, -0.06435941038671157, 0.3854845277687917, 0.6911088388028229] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.6650964387751211, -0.34961073112696767, -0.4316460762174112, -0.4990999185490129] + v: 0.125 + - phase: A + O: [0.1643442326674122, 0.21205555067771598, 0.18237328729946675, -0.9459193415378059] + v: 0.125 + - phase: A + O: [0.5079103592861302, -0.4522879915621313, 0.7008603696203147, 0.21507529359320504] + v: 0.125 + - phase: A + O: [0.4588629674996609, 0.7103482146539822, -0.14094577428597305, -0.5147664321867083] + v: 0.125 + - phase: A + O: [0.044305288641285946, -0.3875768281048735, -0.7143901476515312, -0.5809199261972351] + v: 0.125 + - phase: A + O: [0.8455643302581954, -0.4342346154649184, -0.29235576797838947, -0.10483018199359342] + v: 0.125 + - phase: A + O: [0.5790795198800359, 0.5645942182636775, -0.26425181035873874, 0.5254248367567554] + v: 0.125 + - phase: A + O: [0.6475654656469717, 0.04725837905512413, 0.4718561325845725, -0.5964707901086468] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.9334013387182871, -0.3485154208652402, -0.04006434439320742, 0.07545721043330728] + v: 0.125 + - phase: A + O: [0.38741862953083567, -0.9054265066714982, 0.12281627778824236, 0.12257980428821813] + v: 0.125 + - phase: A + O: [0.8578234268453049, 0.25286192172706, 0.21735917871049656, -0.3910943675459601] + v: 0.125 + - phase: A + O: [0.4841852989554279, -0.5324884938481191, 0.6128392956763806, -0.32626461326610684] + v: 0.125 + - phase: A + O: [0.24479559088002964, -0.39790158622306016, -0.6885075670842895, 0.5547132380199182] + v: 0.125 + - phase: A + O: [0.006342119419357721, 0.8016474931043842, -0.09875135732320732, 0.589550034982232] + v: 0.125 + - phase: A + O: [0.5815233878895042, -0.41292157227416415, -0.6523344380499, -0.2564880219859532] + v: 0.125 + - phase: A + O: [0.08441325811399321, -0.9287379499833768, -0.04047714959468877, 0.3587224867163255] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.9272909114072972, 0.22505658735105372, -0.12087397257258231, 0.27362489080097285] + v: 0.125 + - phase: A + O: [0.22477798467053944, -0.16730490431874273, 0.7619888558500476, 0.5838295214860949] + v: 0.125 + - phase: A + O: [0.6944164222400087, -0.3089622138004769, 0.47430811205294454, -0.44425217816873547] + v: 0.125 + - phase: A + O: [0.9319464859005648, -0.33314612927635295, 0.09454266632036588, 0.10747598899664906] + v: 0.125 + - phase: A + O: [0.7631364561921935, 0.6348137033139695, -0.07779160762534851, 0.09264327875398014] + v: 0.125 + - phase: A + O: [0.30213352773158436, 0.7607414448583625, -0.5489414690920735, -0.1692662075144206] + v: 0.125 + - phase: A + O: [0.44393342791682283, -0.20509632166957376, 0.6929260547202925, 0.529822699688679] + v: 0.125 + - phase: A + O: [0.5553300723266665, 0.8100017529476545, -0.18277171291698383, 0.045827633026130514] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.3369089353527777, 0.11156804371056815, -0.8851691518465128, -0.30086627182417736] + v: 0.125 + - phase: A + O: [0.1904884889827469, -0.2955994647758964, -0.5609071888421532, 0.7494786304455029] + v: 0.125 + - phase: A + O: [0.14357497570029057, -0.8835693969815234, -0.07717841484904021, -0.4390157620766682] + v: 0.125 + - phase: A + O: [0.2844319189561915, -0.26616939939342976, -0.09666838434612286, 0.9159189689996324] + v: 0.125 + - phase: A + O: [0.3986740568181236, -0.009203742364828175, 0.3059441820684439, 0.8645070531841439] + v: 0.125 + - phase: A + O: [0.6689177202684424, -0.4911686233022882, 0.011604901743798118, -0.5578241597938561] + v: 0.125 + - phase: A + O: [0.24260666144446064, -0.7362708394584294, 0.555535585659367, 0.3007116091075576] + v: 0.125 + - phase: A + O: [0.8264968442974631, 0.08346800006449286, -0.5223744566842243, 0.19251230177687406] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.5964950823065459, -0.03914167887903209, -0.764986315653944, 0.23970290490697482] + v: 0.125 + - phase: A + O: [0.8080255887350464, 0.369717513486498, 0.4541656797460721, 0.06432063052809132] + v: 0.125 + - phase: A + O: [0.9384315445539018, 0.21987525747326847, 0.26439717033746396, 0.033094465621676714] + v: 0.125 + - phase: A + O: [0.3398146205195601, 0.19417091506154938, 0.7316894460339152, 0.5580808489707294] + v: 0.125 + - phase: A + O: [0.3246633791904426, 0.47411988229633434, 0.8166638950637336, 0.05351737963768399] + v: 0.125 + - phase: A + O: [0.3795740054462351, -0.8471170612518093, 0.01606588144238899, 0.37156176657331014] + v: 0.125 + - phase: A + O: [0.3324564774831089, 0.5840719896629913, 0.33174639891221797, 0.6620248698345199] + v: 0.125 + - phase: A + O: [0.5142455012854315, 0.2115524033587584, -0.25751707686577474, -0.7902417985422785] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.5917389153130538, 0.014487837662305996, 0.1546249763526937, -0.7910286185416618] + v: 0.125 + - phase: A + O: [0.13783983489759696, 0.19317471156196087, 0.9651184311351051, -0.11058989380440512] + v: 0.125 + - phase: A + O: [0.8586698401906224, 0.4868991116453938, -0.04218722674591906, 0.15438781857849304] + v: 0.125 + - phase: A + O: [0.9890970857322728, 0.05214494425397627, -0.1362936500688951, -0.019796482909146578] + v: 0.125 + - phase: A + O: [0.9020138640071081, 0.25707037984798153, 0.30534577613336306, -0.16446813047303388] + v: 0.125 + - phase: A + O: [0.3175523590958934, -0.563302190026314, -0.6464135983869942, -0.40496987760149405] + v: 0.125 + - phase: A + O: [0.752248294923397, -0.30191235437425856, 0.44098110520789696, -0.3853661867764942] + v: 0.125 + - phase: A + O: [0.07541991372724928, 0.21981465995106916, -0.8076581447316371, 0.5419240473835979] + v: 0.125 + homogenization: RGC + - constituents: + - phase: A + O: [0.3735354245257942, -0.19362809638145217, 0.7860424876438061, 0.45289806196843757] + v: 0.125 + - phase: A + O: [0.0320727653734856, -0.8866094001869422, 0.46133859224884993, 0.007862094078374177] + v: 0.125 + - phase: A + O: [0.4437387774582536, 0.2752317472571834, 0.5589728539449029, -0.6441216742466462] + v: 0.125 + - phase: A + O: [0.4189270336917096, -0.7997419507282093, 0.08375652034255085, 0.4217793238031132] + v: 0.125 + - phase: A + O: [0.07774372790271536, 0.8494512032072281, -0.23549059135564554, 0.4657603971191082] + v: 0.125 + - phase: A + O: [0.7403304241587872, 0.5263542470691401, -0.1337642666383515, -0.39619337529526266] + v: 0.125 + - phase: A + O: [0.3862324493674717, -0.7790044035666689, 0.2926767318730596, 0.39789064439798927] + v: 0.125 + - phase: A + O: [0.12717246708576896, 0.2790094483039878, 0.8667779585068207, -0.39328979394229346] + v: 0.125 + homogenization: RGC + +homogenization: + RGC: + N_constituents: 8 + mechanical: + type: RGC + D_alpha: [4.0e-06, 4.0e-06, 2.0e-06] + a_g: [0.0, 0.0, 0.0] + c_alpha: 2.0 + cluster_size: [2, 2, 2] + output: [M, Delta_V, avg_a_dot, max_a_dot] + xi_alpha: 10.0 + +phase: + A: + lattice: cF + mechanical: + output: [F, F_e, F_p, L_p] + elastic: {C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9, type: hooke} + plastic: + N_sl: [12] + a_sl: 2.25 + atol_xi: 1.0 + dot_gamma_0_sl: 0.001 + h_0_sl_sl: 75e6 + h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4] + n_sl: 20 + output: [xi_sl] + type: phenopowerlaw + xi_0_sl: [31e6] + xi_inf_sl: [63e6] + B: + lattice: cI + mechanical: + output: [F, P, F_e, F_p, L_p, O] + elastic: {C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9, type: hooke} + plastic: + N_sl: [12] + a_sl: 2.25 + atol_xi: 1.0 + dot_gamma_0_sl: 0.001 + h_0_sl_sl: 75e6 + h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4] + n_sl: 20 + output: [xi_sl] + type: phenopowerlaw + xi_0_sl: [31e6] + xi_inf_sl: [63e6] + C: + lattice: cI + mechanical: + output: [F] + elastic: {C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9, type: hooke} diff --git a/python/tests/reference/Result/4grains2x4x3.vtr b/python/tests/reference/Result/4grains2x4x3.vtr new file mode 100644 index 000000000..a769a8e55 --- /dev/null +++ b/python/tests/reference/Result/4grains2x4x3.vtr @@ -0,0 +1,30 @@ + + + + + + AAAAAACAAAAAAAAA + + + + + + + + AQAAAACAAADAAAAAIgAAAA==eF5jZIAARjSamQAfXRwdoMszoYnD+DBAyBx0GgYADegAHw== + + + + + AQAAAACAAAAYAAAAEQAAAA==eF5jYEAGD+wh9Ad7AA0uAk8= + + + AQAAAACAAAAoAAAAFwAAAA==eF5jYEAGF+wh9AMo/QJKf7AHADzEBIU= + + + AQAAAACAAAAgAAAAGAAAAA==eF5jYICAUDC4ag+hn9pDRD/YAwBmSwdk + + + + + diff --git a/python/tests/reference/Result/4grains2x4x3_compressionY.hdf5 b/python/tests/reference/Result/4grains2x4x3_compressionY.hdf5 new file mode 100644 index 0000000000000000000000000000000000000000..c3520c27e02a1a048b149654f6417b5ffbf199d2 GIT binary patch literal 781336 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
q=BFK_DlqJ|y58@~--mBNnqx)r<)rkL` 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

dl8qtg+7hf?4{mg;fujAA( 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 a}e<9Z2WeE+L? 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 literal 0 HcmV?d00001 diff --git a/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.yaml b/python/tests/reference/Result/6grains6x7x8_single_phase.material.yaml similarity index 100% rename from python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.yaml rename to python/tests/reference/Result/6grains6x7x8_single_phase.material.yaml diff --git a/python/tests/reference/Result/compressionY.yaml b/python/tests/reference/Result/compressionY.yaml new file mode 100644 index 000000000..cfe67e692 --- /dev/null +++ b/python/tests/reference/Result/compressionY.yaml @@ -0,0 +1,17 @@ +--- +solver: + mechanical: spectral_basic + +loadstep: + - boundary_conditions: + mechanical: + dot_F: [x, 0, 0, + 0, -1.0e-3, 0, + 0, 0, x] + P: [0, x, x, + x, x, x, + x, x, 0] + discretization: + t: 5 + N: 10 + f_out: 2 diff --git a/python/tests/test_ConfigMaterial.py b/python/tests/test_ConfigMaterial.py index 5ac0e546a..91ab3453b 100644 --- a/python/tests/test_ConfigMaterial.py +++ b/python/tests/test_ConfigMaterial.py @@ -133,9 +133,9 @@ class TestConfigMaterial: def test_load_DREAM3D_reference(self,tmp_path,ref_path,update): cur = ConfigMaterial.load_DREAM3D(ref_path/'measured.dream3d') - ref = ConfigMaterial.load(ref_path/'measured.material_yaml') + ref = ConfigMaterial.load(ref_path/'measured.material.yaml') if update: - cur.save(ref_path/'measured.material_yaml') + cur.save(ref_path/'measured.material.yaml') for i,m in enumerate(ref['material']): assert Rotation(m['constituents'][0]['O']) == \ Rotation(cur['material'][i]['constituents'][0]['O']) From 4b9fcf2f7724f8a1c8bda3f040b401451ce1431e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 1 Apr 2021 13:47:27 +0200 Subject: [PATCH 086/219] testing new read functionality --- .gitattributes | 3 +- python/tests/reference/Result/read_0.pbz2 | Bin 0 -> 286579 bytes python/tests/reference/Result/read_1.pbz2 | Bin 0 -> 48 bytes python/tests/reference/Result/read_2.pbz2 | Bin 0 -> 60341 bytes python/tests/reference/Result/read_3.pbz2 | Bin 0 -> 93544 bytes python/tests/reference/Result/read_4.pbz2 | Bin 0 -> 32161 bytes python/tests/reference/Result/read_5.pbz2 | Bin 0 -> 48 bytes python/tests/reference/Result/read_6.pbz2 | Bin 0 -> 1172 bytes python/tests/reference/Result/read_7.pbz2 | Bin 0 -> 7734 bytes python/tests/test_Result.py | 39 ++++++++++++++++++++++ 10 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 python/tests/reference/Result/read_0.pbz2 create mode 100644 python/tests/reference/Result/read_1.pbz2 create mode 100644 python/tests/reference/Result/read_2.pbz2 create mode 100644 python/tests/reference/Result/read_3.pbz2 create mode 100644 python/tests/reference/Result/read_4.pbz2 create mode 100644 python/tests/reference/Result/read_5.pbz2 create mode 100644 python/tests/reference/Result/read_6.pbz2 create mode 100644 python/tests/reference/Result/read_7.pbz2 diff --git a/.gitattributes b/.gitattributes index c2785cf15..1437f7412 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9,10 +9,11 @@ *.hdf5 binary *.pdf binary *.dream3d binary +*.pbz2 binary # ignore files from MSC.Marc in language statistics installation/mods_MarcMentat/20*/* linguist-vendored -src/marc/include/* linguist-vendored +src/Marc/include/* linguist-vendored # ignore reference files for tests in language statistics python/tests/reference/* linguist-vendored diff --git a/python/tests/reference/Result/read_0.pbz2 b/python/tests/reference/Result/read_0.pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..6649f999421b302228fb397dacf08fccae603adb GIT binary patch literal 286579 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�}YMVC~=sCH_B^}eoWK63;uM6ANYIHrP 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�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�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⁡)?!VA%M`ZE4rYkaUbEQU}+lOVSQ!{NY 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 literal 0 HcmV?d00001 diff --git a/python/tests/reference/Result/read_1.pbz2 b/python/tests/reference/Result/read_1.pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..c1963d4eaf5b3c808081454a4553c95097f00396 GIT binary patch literal 48 zcmZ>Y%CIzaj8qGbd?Z-;kb!~m!UGl{$-v~mz`~%wpxD+pi#fQkTqU@blTT56o&W$p C8Vo%E literal 0 HcmV?d00001 diff --git a/python/tests/reference/Result/read_2.pbz2 b/python/tests/reference/Result/read_2.pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..c8398ab2f7215f8d962840ca8773c46c685d3935 GIT binary patch literal 60341 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

95+Jg(j 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 `~hUxC4vDq;RZrHQl$_~cY>f&oUhU>w>d!i+O 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 C8Vo%E literal 0 HcmV?d00001 diff --git a/python/tests/reference/Result/read_6.pbz2 b/python/tests/reference/Result/read_6.pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..4459d2e5940ef930e00e6fc49c7b624b0ee473da GIT binary patch literal 1172 zcmV;F1Z(?3T4*^jL0KkKS>|wc@&E(HfB*mOH{9s||M!01-D>~;-}isz{z(7-|4&zT zd*{#H72VJSegPE%kcdRoWC^3x^rQ7pMy8C^WN2vGo})&drqndirh%i<27#uBsh|KJ zrfMFh(rCgBsp@*3YA2}B9;Svzr1c(}6KZ)x8Zrh=0Ay&>Kn9phh9Rbn27mxGXuyp! z0B9KongNhBGzNxDfDIY|156NT$Qd*Nk)urj8euXRhMF`Q007aW0yM}0pkx|o20+lz z8W}PGG-v<~FhQdrWY7jijWhshgveqVXwYZ?14fJp(;xM0BF(bGzObf(f}Ty)70940j7We01Y_7 z&w!0omQaj{Rv{TcL=u7_R>a_;JOUFykpRR&0I>lOsStuhAQ1|Y2(bz;02ol#i~|D# zCR7p_$Ay?+f$0)-`z9PoyJ?DBh)E-xQ|6r~QfMfbbvkaYxml8mV@!x3YmUNJEkl^&ax!(qvNRAkLy$QG0|P+q?d_~vG4AD(4PnU~fsn{;T3bW2 zfuuKMHG++(+Zto77#dw@)3sXXa5Qy;0cxno)kRpqrDSgg?!eL-b7|tw^DvJWNF)M* zteFPxbd%yXC7hyG459ep!o5Er%<3>Pa1=6y)@hlxoxy;P4{dLn8DX%j&Uhe}fm-vP z!>_nyMD?yz@LwzRFg4K>j9txvu+)1UJJjzPu~khJl&&J8tkm}@v~{H*FnwIPxr)cw zM2;e$RaXk7llYcb{Act!jH@$`k%neMW%LbU~#)lQO;>)lT z-b7#kEG`5t&>=W?ihu<}VlM$o|5IR#j^qIgfY)u~uFqMYa1($C2z}YlI zRB?wGeV7QlO^6A}1DU9Z>d8z%j!O~<*G!j>mliqpB)%Yl1TiTkHfan?p{R8uW=0

<+ltP6D+Vj%=aOr%s-S9s;>+?6=P&z<&o6dW6=v7nO``|mlzo2Z_ z2WA3QfF)D{N}v;(fYpGR${FP4e7Le2+U25yP3;}2u6M<+dHwrFto~WM`|;r)C5MVV zK1r!uFI9(ilR-$c3!v`*9qk(IDH!uDi`A0@8Z?LSWyH%+23};ZbEz?^Ew&VcjWVd< z>yj6Q1i1@J8m{09XFD50x3lQ?jIT1K^c}r%?B}Is8~pM0YEK-?LSe;7fi=7HyR%Ww mn~+ON)br<}@zm2zg19EZffzu<0Q^Az;_gVN3KAU74!%IZy&%;9 literal 0 HcmV?d00001 diff --git a/python/tests/reference/Result/read_7.pbz2 b/python/tests/reference/Result/read_7.pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..ef25acbf96aa769bee6cff443e5ed594eb421e7e GIT binary patch literal 7734 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 w(gks^_W$84g~u8r3 Date: Thu, 1 Apr 2021 14:56:17 +0200 Subject: [PATCH 087/219] simplified --- python/damask/_result.py | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 7b26357cd..35bb63989 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1354,27 +1354,20 @@ class Result: for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{},'geometry':{}} - for la in labels_.intersection(f[os.path.join(inc,'geometry')].keys()): - r[inc]['geometry'][la] = _read(f,os.path.join(inc,'geometry',la)) + for la in labels_.intersection(f['/'.join((inc,'geometry'))].keys()): + r[inc]['geometry'][la] = _read(f,'/'.join((inc,'geometry',la))) - for ph in self.visible['phases']: - r[inc]['phase'][ph] = {} - for field in f[os.path.join(inc,'phase',ph)].keys(): - r[inc]['phase'][ph][field] = {} - for la in labels_.intersection(f[os.path.join(inc,'phase',ph,field)].keys()): - r[inc]['phase'][ph][field][la] = \ - _read(f,os.path.join(inc,'phase',ph,field,la)) - - for ho in self.visible['homogenizations']: - r[inc]['homogenization'][ho] = {} - for field in f[os.path.join(inc,'homogenization',ho)].keys(): - r[inc]['homogenization'][ho][field] = {} - for la in labels_.intersection(f[os.path.join(inc,'homogenization',ho,field)].keys()): - r[inc]['homogenization'][ho][field][la] = \ - _read(f,os.path.join(inc,'homogenization',ho,field,la)) + for ty in ['phase','homogenization']: + for na in self.visible[ty+'s']: + r[inc][ty][na] = {} + for field in f['/'.join((inc,ty,na))].keys(): + r[inc][ty][na][field] = {} + for la in labels_.intersection(f['/'.join((inc,ty,na,field))].keys()): + r[inc][ty][na][field][la] = _read(f,'/'.join((inc,ty,na,field,la))) if strip: r = util.dict_strip(r) if compress: r = util.dict_compress(r) + return r From 84e117c6b36089f6e0a18b9aa46b05d8f81c96d7 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 1 Apr 2021 15:52:43 +0200 Subject: [PATCH 088/219] polished and added tests --- python/damask/_result.py | 97 ++++++++++----------- python/tests/reference/Result/place_0.pbz2 | Bin 0 -> 40927 bytes python/tests/reference/Result/place_1.pbz2 | Bin 0 -> 48 bytes python/tests/reference/Result/place_2.pbz2 | Bin 0 -> 10851 bytes python/tests/reference/Result/place_3.pbz2 | Bin 0 -> 17373 bytes python/tests/reference/Result/place_4.pbz2 | Bin 0 -> 8573 bytes python/tests/reference/Result/place_5.pbz2 | Bin 0 -> 48 bytes python/tests/reference/Result/place_6.pbz2 | Bin 0 -> 1269 bytes python/tests/reference/Result/place_7.pbz2 | Bin 0 -> 7687 bytes python/tests/test_Result.py | 37 ++++++-- 10 files changed, 77 insertions(+), 57 deletions(-) create mode 100644 python/tests/reference/Result/place_0.pbz2 create mode 100644 python/tests/reference/Result/place_1.pbz2 create mode 100644 python/tests/reference/Result/place_2.pbz2 create mode 100644 python/tests/reference/Result/place_3.pbz2 create mode 100644 python/tests/reference/Result/place_4.pbz2 create mode 100644 python/tests/reference/Result/place_5.pbz2 create mode 100644 python/tests/reference/Result/place_6.pbz2 create mode 100644 python/tests/reference/Result/place_7.pbz2 diff --git a/python/damask/_result.py b/python/damask/_result.py index 35bb63989..e49c672be 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1326,7 +1326,7 @@ class Result: v.save(f'{self.fname.stem}_inc{inc[ln:].zfill(N_digits)}') - def read(self,labels,compress=True,strip=True): + def read(self,output,compress=True,strip=True): """ Export data from file per phase/homogenization. @@ -1335,8 +1335,8 @@ class Result: Parameters ---------- - labels : str or list of, optional - Labels of the datasets to be read. + output : str or list of, optional + Name of the datasets to include. compress : bool Squeeze out dictionaries that are not needed for a unique structure. This might be beneficial in the case of single @@ -1348,22 +1348,22 @@ class Result: """ r = {} - labels_ = set([labels] if isinstance(labels,str) else labels) + output_ = set([output] if isinstance(output,str) else output) with h5py.File(self.fname,'r') as f: for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{},'geometry':{}} - for la in labels_.intersection(f['/'.join((inc,'geometry'))].keys()): - r[inc]['geometry'][la] = _read(f,'/'.join((inc,'geometry',la))) + for out in output_.intersection(f['/'.join((inc,'geometry'))].keys()): + r[inc]['geometry'][out] = _read(f,'/'.join((inc,'geometry',out))) for ty in ['phase','homogenization']: - for na in self.visible[ty+'s']: - r[inc][ty][na] = {} - for field in f['/'.join((inc,ty,na))].keys(): - r[inc][ty][na][field] = {} - for la in labels_.intersection(f['/'.join((inc,ty,na,field))].keys()): - r[inc][ty][na][field][la] = _read(f,'/'.join((inc,ty,na,field,la))) + for label in self.visible[ty+'s']: + r[inc][ty][label] = {} + for field in f['/'.join((inc,ty,label))].keys(): + r[inc][ty][label][field] = {} + for out in output_.intersection(f['/'.join((inc,ty,label,field))].keys()): + r[inc][ty][label][field][out] = _read(f,'/'.join((inc,ty,label,field,out))) if strip: r = util.dict_strip(r) if compress: r = util.dict_compress(r) @@ -1371,7 +1371,7 @@ class Result: return r - def place(self,labels,compress=True,strip=True,constituents=None,fill_float=0.0,fill_int=0): + def place(self,output,compress=True,strip=True,constituents=None,fill_float=0.0,fill_int=0): """ Export data from file suitable sorted for spatial operations. @@ -1384,7 +1384,7 @@ class Result: Parameters ---------- - labels : str or list of, optional + output : str or list of, optional Labels of the datasets to be read. compress : bool Squeeze out dictionaries that are not needed for a unique @@ -1403,16 +1403,17 @@ class Result: fill_int : int Fill value for non existent entries of integer type. Defaults to 0. + """ r = {} - labels_ = set([labels] if isinstance(labels,str) else labels) + output_ = set([output] if isinstance(output,str) else output) if constituents is None: constituents_ = range(self.N_constituents) else: constituents_ = constituents if isinstance(constituents,Iterable) else [constituents] - suffixes = [''] if self.N_constituents == 1 or len(constituents_) == 1 else \ + suffixes = [''] if self.N_constituents == 1 or isinstance(constituents,int) else \ [f'#{c}' for c in constituents_] grp = 'mapping' if self.version_minor < 12 else 'cell_to' @@ -1423,10 +1424,10 @@ class Result: at_cell_ph = [] in_data_ph = [] - for c in constituents_: + for c in range(self.N_constituents): at_cell_ph.append({label: np.where(f[os.path.join(grp,'phase')][:,c][name] == label.encode())[0] \ for label in self.visible['phases']}) - in_data_ph.append({label: f[os.path.join(grp,'phase')][member][at_cell_ph[c][label]][...,0] \ + in_data_ph.append({label: f[os.path.join(grp,'phase')][member][at_cell_ph[c][label]][...,c] \ for label in self.visible['phases']}) at_cell_ho = {label: np.where(f[os.path.join(grp,'homogenization')][:][name] == label.encode())[0] \ @@ -1437,45 +1438,41 @@ class Result: for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{},'geometry':{}} - for la in labels_.intersection(f[os.path.join(inc,'geometry')].keys()): - r[inc]['geometry'][la] = _read(f,os.path.join(inc,'geometry',la)) + for out in output_.intersection(f[os.path.join(inc,'geometry')].keys()): + r[inc]['geometry'][out] = _read(f,os.path.join(inc,'geometry',out)) - for ph in self.visible['phases']: - for field in f[os.path.join(inc,'phase',ph)].keys(): - if field not in r[inc]['phase'].keys(): - r[inc]['phase'][field] = {} + for ty in ['phase','homogenization']: + for label in self.visible[ty+'s']: + for field in f[os.path.join(inc,ty,label)].keys(): + if field not in r[inc][ty].keys(): + r[inc][ty][field] = {} - for la in labels_.intersection(f[os.path.join(inc,'phase',ph,field)].keys()): - data = ma.array(_read(f,os.path.join(inc,'phase',ph,field,la))) + for out in output_.intersection(f[os.path.join(inc,ty,label,field)].keys()): + data = ma.array(_read(f,os.path.join(inc,ty,label,field,out))) - if la+suffixes[0] not in r[inc]['phase'][field].keys(): - container = np.empty((self.N_materialpoints,)+data.shape[1:],dtype=data.dtype) - fill_value = fill_float if data.dtype in np.sctypes['float'] else \ - fill_int - for c,suffix in zip(constituents_, suffixes): - r[inc]['phase'][field][la+suffix] = \ - ma.array(container,fill_value=fill_value,mask=True) + if ty == 'phase': + if out+suffixes[0] not in r[inc][ty][field].keys(): + container = np.empty((self.N_materialpoints,)+data.shape[1:],dtype=data.dtype) + fill_value = fill_float if data.dtype in np.sctypes['float'] else \ + fill_int + for c,suffix in zip(constituents_, suffixes): + r[inc][ty][field][out+suffix] = \ + ma.array(container,fill_value=fill_value,mask=True) - for c,suffix in zip(constituents_, suffixes): - r[inc]['phase'][field][la+suffix][at_cell_ph[c][ph]] = data[in_data_ph[c][ph]] + for c,suffix in zip(constituents_, suffixes): + r[inc][ty][field][out+suffix][at_cell_ph[c][label]] = data[in_data_ph[c][label]] - for ho in self.visible['homogenizations']: - for field in f[os.path.join(inc,'homogenization',ho)].keys(): - if field not in r[inc]['homogenization'].keys(): - r[inc]['homogenization'][field] = {} + if ty == 'homogenization': + if out not in r[inc][ty][field].keys(): + container = np.empty((self.N_materialpoints,)+data.shape[1:],dtype=data.dtype) + fill_value = fill_float if data.dtype in np.sctypes['float'] else \ + fill_int + r[inc][ty][field][out] = \ + ma.array(container,fill_value=fill_value,mask=True) - for la in labels_.intersection(f[os.path.join(inc,'homogenization',ho,field)].keys()): - data = ma.array(_read(f,os.path.join(inc,'homogenization',ho,field,la))) - - if la not in r[inc]['homogenization'][field].keys(): - container = np.empty((self.N_materialpoints,)+data.shape[1:],dtype=data.dtype) - fill_value = fill_float if data.dtype in np.sctypes['float'] else \ - fill_int - r[inc]['homogenization'][field][la] = \ - ma.array(container,fill_value=fill_value,mask=True) - - r[inc]['homogenization'][field][la][at_cell_ho[ho]] = data[in_data_ho[ho]] + r[inc][ty][field][out][at_cell_ho[label]] = data[in_data_ho[label]] if strip: r = util.dict_strip(r) if compress: r = util.dict_compress(r) + return r diff --git a/python/tests/reference/Result/place_0.pbz2 b/python/tests/reference/Result/place_0.pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..e8a7d1399d3fd9d44c753476660ea67d32fe869b GIT binary patch literal 40927 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 w zML9}2-vK55Ds8(r;Y`R9Y?T>1+nY{$tl`V4tjaWbrwxJ#Af|a3k7o|jw71D{s~rOL z>OvZ#SnlX)#=oMO#T8hvkK6ibYJQ=ws+v`w1ncUQvYFJ(ZynNI{z8}xt`D$Z4vi@$5W397x)at*d(0<=2J6ntRI9V1J z1PpjWNpEUcKY$qDWAro&hgilIsqHqrf)CpiOB#U0IMzgAOZwhU1dipBhQRz3TQv4nVDVcU)cV@ZeWx7 zUS4-xT8vwWbE!V*N1j0`%yJb!SUxr`iZLkB0bzael_`73bahr0GH$TePPCf<(chCl zGltWy_AK02m8Wd328%+M#y_)DyFV)y9Ocq6_SZx4CmoqTRROSC=S$q&P-=|2*d252 z8&~qmf>({<#WUKpQj`tKgDHC6G>crk;+-D=b_f8}ob4<4JFXA}p8i2V@WEZTv2aOP z5E%=*KwC5oD{o^mhSr~VqdU|r0D=gWcIJc}J^7;Kx>1I^di4aT7HQq+rb>%S0D;Q8 zMpve>n(-3EzEskJDT8#-9O6Y6I`vxU+0ZfEx~gxQzj3IlMVU2fGplFDmVmS(jkc@u zirPU<xOJ~A{W+CqJMX)UI)$NhS*72}wU<4kIpt421R)9{1VkVp z&8AONT8_3ywn?UhIz{?g+cnVvm5Uu1|#0!Zt<6!eju?aZaRIBQxOXlyQffmVDj(YswDw7eVdsA zyt%i%Ctrn!@pw3$rGpi^{l-}F`OvGSdPH8U9rt>x1|}R4005PkthcyDXyP4xApr*U zg=b`+9^(;Xy!d=l^jfdNr}uDL>_=7g8Lb)csSjRgEv?QK zMCXU{1O*C=mx1(hV^YwhK=VWYoc6Rr12lD{Dubtl?Vw3GbmytLj~DRK1pMhO zeXQY1X93l)3n}-42K@uKXZbf!Fd#u3*ls0z{x1cpZZwkE{IMqIEK5G~*>kEGE$yCC zV7{kntTpN`sW{jG)c7hwU6n8KU6E~pa}44*)W;9i(lwF1|8sa-ousy+wdB}&myzfE z78C>2cwtre)BQ_N2&V0&!n(qbIEmsU;gZD#{n>Ph>*b_**Cyx-P$2w5(GEzi{hHI; zwzIysA?Zo^J7`VlYf~J5HgWC){YxtD{rvy2-l(x|*^a!F9&nuE#xY@0i}&M))PE0& zCP(`x6ODWX#0@I|JCC6Q)f@q>lVTVBAM%L_$aMk+`JS<1zX!)~-i=D=P$Pf<+rIN| z^UHs#AKkz6O~dV+si&N9tv6lXqQw@G9j0P1bR0A{&Y)A|B#?k_x!8V|QyPE6YkpeE zLT1)1qxJ3-+VGo^YZ=svZ^rh>uh?O+>_kXNX34?U* zIt-!C+aoY*F=S6i!IEJ8`{ps{Xt~)Z_gd97=1lTy?(}Iw^ZctGM&j+M{pNGYFUR;e zFHe1dbMhzUv#2smG~f&_R$0isBoTVIgsn7zR?4lWN02GY5)N%v=B z)a{pDS@V+DR%5~h5ZZyPe_QlACHw8M|9V4|$f=G_xWn?T52`yY9CuS1g{0xt@BHiI zRjC<9M9ZcuW~DxxqkChwca-M}%G1=+to;F(*zq+su8jND%#HyFDuE`Rh>POr0&%o& ztYhai&73sL`clWapUN#+3$JF) zLIH8{3tkG{+TpKy0nYzO8KQPq(dfOWnKE-i+z+RVhU4Ih0I`<82uSQ3jGyC-0i;eG@7wV#j^<7=vEc%fHnv}dTJWnJ9xkk;> zSO!Gv2L5U3n1y`$qDSDc@KleAU^(8$9s!+zL$ydzWBbmLNTNk$rYNjsvgtWHSGLyv zNMvMwDRiGp7gmKlH)G;ITpw|{)A3!)n*h=Jj&tQ-wro6Tnm{8i zhxIv?fmjX(A-wI14luK-!~|S9rjk7mCekWC*+nIv;X66+59A216=Z~_<655#m)mk@ zteQokEKydSNYXL5lc6VM=eRNs^!Bgf`C73#;?Ho^D21c+6@%W{>y7r{Pfe6{8!jAn zK6>D^9rPmYI4hlX3F9BH+tZTMectdYb<4o52wf|~nN%_ct8Ai>9e-1ue8vWI-u ztYFEa!U2U85EnuMVm`pHU4Zzl1Cc`*&mas?b+fA_cv#C2HrQz^TS#;{I1YmTh2l@= zaNw?;$Z`aLH{Sq31DHzinE*dbree$M;i&$#4LlTlHi&WU0+2!lQ6AKhQ z4W?XF`(x3X-BN`12-1sM;)nnSwB`8ntp8_mxWf_Y{Mj1VWK$>6l^PRLP3uSTBB&h1uT4EK1Q0%e7@Gm%0o-Z=xMXpCmu!2&56+Yw4pOG@_fqdf1O68qA8=DI}i&j{^%AjMWJ#P2< zMs9cF3FU%KcoKX13v@TzpTqxoh|*^83$NDTtCG#APi0&st~0@`gh{U@D1)*WD#*(7{7~cY zIwii}>#h($<3VQqxwjq0GjH$QvApWII9v6Mh34P+X!@}K6gIR|g z##?1==o|oTK#Tw~G#jdt&eGoAqK|pLs8U8V* zoObJt`M=WS=8QEpakwQ-aG(%^XQPd?ZGV0Kw6;c^|UZ1!REoT3(e>0VvX+uv-_`nGzvTMt5{Pmu3Uu%|lOl)!Ax z3_*!IhV(n!CI0a(7;9d&K1JBza<;{qFNbRg#rDQ1=c?$BRL!(x5YzjrN84L}YE5-) zUOowwrdNe}N1yhd=B@!{t^~Q2!~YYFJ-Xlw2vtG=l#@VK2RI4?%~%pwb#L!opT>Za zpa38IfRd@e6q5=HhjXi39rAQ+ssMq3{oNJ>32qOyU`cT5GPE_VHeUVyv|8bF$c@yd z`8pBmcQ8f9Vs7FVBj}=MU3-jmkW9rQPx@v*Fk*B3P##4dpJ^qA%y^=EgIx$D8^dJA zAYZJIiNm{rc7Ar04MEB;2!mnv8pZ&>#F(hIRy^*J+k@nv<2>bjlG7Fa)GvVQV&xpwDaFG zk%kyR|4CS)@s*4A%2l!P-yaaUdIpb$ctM^p0;J|hi*!%3oxcD<0#uz-6G9K0#A;h) zv>durm&-hBhxH&+vxiclL3JVVtr$dg$4GK&gEOqey-725zw=%`qX|PhTq$n1*_X%6 zLb~EL0Do!63d5|C_n2O$_KoC-sQjVdnL@kgw0B~89>1M(o6iiQ6T86<8Jnr5ZmGJc zvi0(^%bJ6jp(CV&VJ zBdXQu>SRU&PYd4Q*bpz1meAl_Ii$>oF=oa?r_$Y`U-*N-b*HbJ)mCMfpN8((@(w-L z-;Owrs4|^2-&ixejf(M>O%((>KetQ;>pJu_{&U~&q=}80C1N}3FNECkT%XskA z-dMktO`&_rp19&UUa#*}3&LgD?YL0r$k09#xG6bkBR%KAF}JE7)jy#8ktyA}Mqe~L zujS4uY8K>oz&{``NB}Qjpek_$mlw96lBhRFKwx?RlAreq3ASL0&)|Zv6Q<075Dx{ z=40k@sOCXjIDA%}ufuTJ;GhU8lV`l@Y4{ajkq+18f_9!8>gaK&Wfh$L_)UNSNnmdO zCHW7Hc^p+az+6^^&mDJ+^g1rX@HOcD=s8<52B8*R09uy4@- z0u6^3v~INV1>4FUXKh!c=kD5BkdW@x!lReIhhLZEf3^^9pgoH(X$%==Xy(q8$QBB< zznF}ydt2V(2a=qU2Y8b3&hc@S!fWBZFuo9(saVEKIiE#brK#5aw*9{bWyEMg7>#%? zZr(AAaVp(HN^5q%)?h8;i_N=F06_u06W6MkmL}cBAGjJ^V=M>PeYxb3eNd;Vyk)ZMvd24ZT`Lx1Opdb#~yOsR?#CJGlh1uR;dWQ z#yT0Kk=Z?#l8Mr{5gnpRn1uS*C2Pcu z0EXa%rd?)+wb^@T*x5&=!?y9zXgh!)j@4x1w`^a(No7~HCgNWb6l{^m5nP7|9jby< zjdWGG=V=LF^jJXy2cdB7(dOsvHZllwNaW<(z9sH!o2LUy(Kcu zhKr@&28QaA@qq)R2f)CB`a;*+HYn!`B8%^*T`AZeZP$ig6!`hOi#jUQy?4*1q1ahf zH9JwJ8o%U1#XQ9SQfywIPzIK7ISc@T1ykLemjRYkoJLni#Y=U|hO@Sz?1GVua7K_f|KGQG_;$j&aF^ZJ+`=cP2{`e>&p#> z$<;0%-60`{-)Aj@ak|BXj^XfZ#rut#A(agLdU zd#i-&jXx~ce!SK9Ww$5g3<%bx;$mwFDe9vRr@a^ugNzfRa4iZW<2RD$eaA=j=4%= zjn<9uAWbSD+m0|cmuob5xWGRv=O0XH90r?0;r_!BIjXV0Y^Zq)j5=Ht7G=3EhEWp; zgpH=R9}^E5U!@F>jprn+wtLBmyslr}fa@U;r0@a)csaukxX^=y8oLpt-Ic(3K4!6u z!zHDeN2jYVE->y?@=Cxzku+i*NpdruO}l-gT|xkR7_>l1QlM@T+ZEGL#}$a6T0g#} z*-Xbw9s@d}lR@U6g@GuEqPT6p=We#ZQTO+G%h-QvO^yUUmEoj^MQKFZU|)#4Xh53? z0!^e#45iX45N=U*_X6Uy)HfB5;f05?$oVSLl7uR^W=gGaE@Ba+ABGNiFAitJ> ze-l*LDfM%}ol1KR5^y?NEnc zC$=v^j~bNutiK@Db7xLz4BLZSU4)B+U#@XB5I}Pf>jK){GTsz$9wk?^uc%qdSkm=+ zqRE5D*14WYs2jxLDq< zkv2bM0SG*E^V0q7!W`5efjqMm2JNhU)Ri)SlBYg{BN5#MPVk2Y?nZ!q9di%U8TpI7q_iq&aM42vos*u*eY)YFtN; zx`X;Fjr|~LKe=(p^ILnrW_6bV_@e$oI(z3-RgR|bIr_Q42w-3Y%xJ8+&75GB`Ai7- zX9ij{N0~-k=t+B!qTtD7b_WS+}b=TWtCeP#PX`qHpAxQF}8^NA~=(fSmoa!dX+s8|lkH|EpB z9C(tr6g5?RZK;ag6x{1RDfuD8_xBCqaE&FWI|ENoOONvx4vC9t))VQSq=QL4xb(x8(PfQpNXcAQ?uFWeA7?CqEbjWmFTaRea8W!4^7i}O-)lu0or&f%S! zAb}S;#OWY1$pTNsb1bxHXe!l69$9$e^s;5wPb*z2ujKv1m$(eO?=an!t2ME}adi9F zXo-~vu=Mw&rNUaPxF`YLVs%Kygqr!7025%*_o2P|G=I4~hS>Wud;BD7&GtL%!mYp% zAtLj0Q9E`gKDyP@O`qZj$ttf<-08HJjt!-Hvv6#6`v1Q(`p;87&L52Xp7-`+^ zgN@FDXqh$QVxeIqgSi2*zGj?&X;(r#^13xu*%<~x?9I2SjVhH+`7ricz%p6ZJAP+k z_}aqwePFw8XqQ5hwfRTs7Vg~cm;wkD7YEFqT2r$IF6*ClQR8Cqdi%fmRW*|_1of{9 zPN-Dzvy4)@LHIBCH`;b+b=vU_Z1LElGCwA@zEE^m=BwyyJdL$}s-R2gol)h$XTg5| z>TO}U19RMOfH+3Vo*QC${5cJt! zn|JOEj2~i&AY0sIbe2x0)3+vO(~!`zI;Roj%9jp74wT2-a``n>yK%X-tdi&qOfmbK zoqqA;&Tbax<2<5NN*lMgL14Um?B#%r_q$9fgByy_KweJs>sW=D0vmq`3_e8MJuHQ% z>zYUbeY`P^qk1p?pa3Z(Zrq{>7~9i!_%Y`mg_lpp9B~dgr;RamG{1`bAA5kItU`g? zd&lOuR4zkjd-#l5nL8^S00ar$dpZfM)3O`tO zAXB@k7cgn|FDCsB+iJn4Ff%52@BqbDib7Xz0741tU9a<`gomFpy$F?rWAvnE8JdDt z4A}{D^Qfa7bswap2>y_2hBpR}RcUohv@t0G_9&@iYH;ya(Wod2F2oqrekRS|^ z{%^LW>+JJn%1#lf)+HAIdi?&%&R+fzYGBN&;lAkMMZ>Rf-%hNWFOIvZpH&ikJ30^E zfneR(4F*cvwZGZHIQnk3!h{eYEba$vcrc=ix)*ghA-v!7MK5D7-GX3=nT7N)Uhz{JUA^?~c>hu!W8c2% z?@p}(H9S5bvReILqytC7oonU!MAxjfnA_o=K^n`K_pYFjRjqVB`pDB(AzU#;M*2hl zdZd1Ox279f95%8RIoqC`lxtEpJ;sMtYJLT9rFmE#AE z(SG@j!~hJ1Z%@g*b?e;*y3{|?Iz&KiSMF5Sv`d9(x3F;x=VRHl85(Dqm`^g@D#$#V z+O9Q0LKO`h5Ny43YvWEGsz?vj(!C^REzks1=3Uk>^p| z+l}%cikD{XyYEhm}Pk^@i~WOq%K0L<>^Y5_B33{!Gl;E_-K(6M0wkI}B}$SRMKj zZ7@zpWSSEH#7PG2iJhGmk1RHyC!!Xg@x_GoBREB~- zE!;+DLI|XUe}_YNvD4#aoA_+m|26;kxT(`yH;uWoV${LLZ;27HU9KQr!E_TSK}rd3 ziaN&f1}Hf`XQ%u~(K?ptSP)Z(Ffp`;lj5#biKZOW_gaJxk(1^M?89s$0f_@$i8n&+ zgUXe3;b~g1(epXmoDifD=c~F}hnq1}q3YXmAN-&hxV6Un+p%?xvn05C@UZ*JliNuy z;+&-o%5y|b#O?}4p2ZP`8F8VKqKUoz9cnQPf0KKX0Nq?MS6EKyO!w!N-J~NN5h1j7dc(p7 z^yH~%iM2|atMo=fgT;V|Et+z_hWGf!uOxIgY2UT=jh@)j-z7;F+@yV&Vvaxwix|Y~ zoDJbc+x7U%Hd=KBfIM9%ud3WEXl&?!_0TmahYg7RA*)DqVlldz9KUmjn+6qOkTMak z7k;^ZoI6aAo*Esk4-|B6^YaN*AmBuVAku#r5Q9tmG>Z&_$JXl5-?GfFdqrM7a}o2X zAIA|_lVby!ytm2)j`Gd_KU5hIGOy~Q8!&O>W^Fw*ZH?LcOO$B)e;p6;2dEH0i$v)l z`nIh*EHaLmJ3;{;Ik%vCltQRtRG00J^=erfKTf&7bl%WW4FPn4J? zk7>r;5CN$Kec+%7!gySG?P%V2Eg~>Um6~LIc?7}>)9EvM^QtPmyb7MMLJWm)f(NX( zT7<6PX{vACWw9`8^L}2^dA!T~Qy)C=d2yG?nw9Go&)P6b4k`QEgA2kCGfYx@k^~Sj zu*=<-kKx))CN~G72p}A}ZDRKBcE`|3?0~*WHbZPud(;tZWHPnWx^3vb^Q2Rvk+uHq z8D{$A)U-31q#iL2nV(%%O7S06yO9959~|I9;%Eh zOg)8J=M=WHf{Tjg@@LXXDCLOEq5&K9p3k$92w!^d_Af;0;?P6}pGl}J@0B^yK9(!!sZK@xCQ;J+%CSv;RAY^Z$3*=p*!hu-T3{EeG)S+$r(&s5gcB<<0)B zMMuoklo;?LqcEZXAj30b%z=O)i_m~K3t=2jz!e~~E5!t)+o zjG~b2&$;BC8Bf5XrKmygQr>jag@|rh3PLLd2B{z-vHou_0@nSY`RkfNu2c@eDd%k*Nvu9x2_7q+-9Xmvd*vxa+_=O+lc{_Cigg(XAU_;qWuF)9 z*I%sKtuCdTW^Lg5hQs%9BZmJrFmv8(;qf(a+Pv?f*L7W8yH4Oz=r(KDJeL%IW@Q6x z#yoISsWGuHhfY9SS*m<%u2X9!Msm{dDwPow-TO95h@kgz`)+s4>fYot-BXf&Bst}OIrA^(}moVq$jf<)eZ_}7UPO8%dd78*`f zswo>1=SY7RuyvY6FGXu94;c2)80GAo$Q42UZ{aMeR#y=+BEq`1PdHlFuG=dj+V5Q4 z)mEMj4a#(Snu6r0Kl4R5;*Df@wzJ4&RK7p+Usl3bGGSLe1k`mzu;41% zgLZ;tuoXfF2JteBr;6R41{VndS}cdO7f-%?yp(j4E#rN)>w1|W!0znW)x^N+^uz$a zjBKnh=qE@On*dX1tWHCU;x%;n_~^FUOJ4&+q}8}(3%C=pOxJA9y=JeXd9%5chji7X z%Ej2($4^Q0Nn2NzwWexUGqa|X|6;-QvE#-x)%s2nNSeg6ooLCDEV0s44AJxmETkW4 z&sY-L0&~z53cS9NB-?xz6sNZcOiR%9?%<~85Mw)J{Hf+<%LU5&+YIbMkko3`U6FaA zyNfol;_$7}Q)prY`}z1;ePm|nES2-Lf2MB_G96lhhrx-?%`FYCnneR3n)lOJ6Gzgk zgdVsWnkrHgBP&~bZ52MfwipQMStg3iUah^sw2_s7S{2^(MYS11+lK4{m85NH_DPo3 z)Ger*1Yh@OgszHaz+|XWEGis0Tvd`PtWD}G@w%5Yf{Uj^EC#aIu8~GPSdxn#(}(*0 zr1u(@)n+DyMj8nZ=*>SpL{-J-7}UaVtsNzG8zrFxmaKb zFxw9EOPlZRsCDPNd8dn^&hdMlI!bv1Rgi;U_j$c!d;}~QPi`h+KwGD#isp41Nrb(| zVpU_nZ1#TZH8psT-Y&B_+f<%&llFJD2E%CxNxMN?%(Fy9AJqV2bZ8~_7FvD8r$MLw zh0i7aCs)Dc_4X@QS+a8;^QDymsPOn?rAktC&vcC8aDTbR7z3KqVe0qgwY5!+*{olU z+Ek{x3wu_$>gjUjpF4TtR}y_l06_#=SI&Gl3RNs}A8Xe3&KyCS#}hx{KouWv!`~79 zhG)g(=&uu04g5XT;mcxM-V1C(RNzRBurM|&&rC0bTarfo;;NXqqDqq@NbH**DJMQ} z4egwgry^qP>h+^L=ladJT;ynP3gH`6*y>~&!praqRRLDGEtL0Q zcACsbl&|o#zu1fC1_cd*4&{*-ok$IWJC-K-!$ck5TfwZ96m;8$??n2^y1!`6z}vWG zyh0PQME9`13byk2x@u^Lc$t9Z0#}MgPEzl!=Gw-xl*}J~`r9y`Pv+55?y4y|Sw$ZH zf)E6Y;yW@m{p(!U>6D?k`5p;hfjVL)m>pTA)a5=5RN?A$#eBqc)i+Pw?99-(-RfS!s5m~kkJB(zh zB)t-DcrlV#*E?Kr-kcMitbB3q*e|qlPDOD)o5AGIs}Qh0zUba~K8~Mig0L_I1)+cd zZfG8wDU-q235#UoM&N=4kU;{nk;(zCegQ4rIQWy|Io+LosZo!@Tfe*X$Ezek1J+0k zXB3y!7&3UHV=vYOV1OV~XOjnxBg8Vnd|4XCyDDylCEZ8@1mi7)z40{m@cnIxllv#; zq;ywvYIvN*Zms(FRgJ#)!;j;fdoxJjhSYTqiJxsU7#GX`vI3U5kl2z4Aa9a`^Q3AE zSJ1R!s?QGAFg?teF+m!gPzU(fmDa-C8iuukkgx5|VdRf-r8f(B_@{>Z)2 z(pb>fA^UVN>{pH%E0@xE(U@n4IgS3{{WmXx1PC{e7Nay$#`RY*K}#Wc z42tH$a-N0bd;_L?Fp{9gdv1QLl37)GjLNi5htzduds5z2rx&W?v%f z!9u~S)$WKIigXQ(^!v_AOA6Jo%`a^J&-r|iy6Ymixj>N^0tDJ4q-i8ZN zHLBywy_y?6PD_vMfrqSyj5w$eL48Go8W2LiZ=oLlS1`CtL%UFq-;<`$j!D*unpxJ0 z$($ibMH~50f&`i>?kLx+frxuuT482@gwHrMzkIACl zOAZPaiF>}Y6%4x%OR%3NnmvQt9^z8Ks#^nt|_!cNJgqn%B;gS$Xu@L)2Ym7&#pB;f9XjDfu#=Xw3ZfOr9 zW3Y10^~pn&SgaXp>LJaXyUAq6DzHTeOXMUr_rmXIq0r6pg5I_)JF9jS|_ZFIp zol?cD>mA%{k0p^Uo=>03HwK(MtzaXnv!*N$^N1Q+G0_QWWpY>EJ^(;jl^$IC-c9^u zuyF4A0;k!c*fFNS5C+tID#2lrGwT2(?Z1N4`oG`9#A+sQ{%iD;ivyYdn3%KB^1k`_ zPr!NiJ^p@!W_#!4FfQ7AMx96Y8fW)R)foGpnfO{lSuYFz-;aTLrbX=mMHpncGra*^ zgiq2KkH`32Lrptm^bc9*__u5v%Usj%^(e^y{2{w=bOZH1O1&$yG7!&{=zb6OqBG7B zoDxENGugw+Wi95Bb`)y=i`BF%m@u8zoaoH%gY((N0#L)PD7FV>LSbp7 zUJr#e6!9H(n2I!x-gJeIZERd0_IgFeHZ~5Q4A0yXIbEhEmTyUmE6StRoks@elu-I8U++87!BG1_np6#DMpReFnxlyI z&dZA~fgqB|1Oe+^CgSO|y55_qs@pH#Z2p2ozi8@*X8$l+OB+#`3}`JvaD65em(814 ztzilLO(ptbeOrr5D)8q{L%_ruI{0a<$6iVg$n&7&VyKJspd+UuW@2i$i1>UedhczH zBC$SMf&?6c))e^Yy+_s^E^cV}K__4n3!rqj z76!QxoOwJ|uMF7E76qLZR5KrEUkK-7Z^loNP0$6=zY;3$#i9)N^35jyW6N5(7O>Z1 zLoY}HR3EG0g4z!U?&)>>_+>J&1_2KqLDf`y?W9u{LBJq2)pyjG9jA$x8xsAF|EW#N zh!)1jb4|dLF&(WYOFVB!yk2lJmRNp-+hoDZU&#rT#zFfBQ~`6O!+f% z3V_HD>#ehQF^k=o>?q%HYV40;Fhb=Z|J!>0KBYSxRIxQ1Je@A_SO45JdSN*$?7PxM zr5^{r4AA6F>~r3#p$K|QCep4!pGkEre#zaAjibk`{<{@uyid=eQx3p3*29)4$&6#z zs;n1t@(fX;uxnW2hXbfyttE}_uy*GWB3xXi6pjW>tElGuwGJEzYq(L|FB*IE>&iJX z6A+3>$;VByw$A)CAX936ium@ay{^u#Xqf^HIrNw+1laj~ujA^?G?caoB_>yN%kuh6 z#had8X&N>wRuoe3{k#rJ>(uEMqEfR~ez$fG{q-5-|K<%^8SI&`A^zjaedK)zq>9j zhE0#ye35n5veD3x8C06U{AcrIExH-Q`RvIyZMeO1PirC?^Km_%-8O5JGmL9y;a-b2}auT*V1V~Obz-FuL1=A-~1%JY&A>zzzzx5GP^Bvg6a$H^>b$lMuJU3W=a#*dq7rD?B%tNeH4AK)=BGpNwGH8@W>D#h4w zb83{V#0K392n7iV6@;COE|~JEra`n;uqCpe|ctX&@0zyLHsQFT4q}hXTef<5! zaxmbLYR^VR?Q(POG*bQy_J8SCa+fE><*SCxIrS??whBhbyEQ%hYpIhVh{5O(#m7n5 zV3cXLbhvZ_1RwW_u4mUF@A)}Bg`Tg+z5Z1%`8)1M==Qk0rUp}V1P4cn0w#DcH2HY| z69+<%5b?Q9mVvbl1JrllqMX`EyuUrXVP-*|@|c**Ho0^;MBU^srwvncy?-PGDkv8@ zTnZKx@+5EP_nAYd(@{J0$zQ$ov%_UASuE2GYtzaJI`2s^40CytxiMXqfBJR=`jX7T zRK`o_qvHySo&bPF<5Nz=dH)95*qSYW-!z_rq2OQycOW^h#OX8B!?)+iFL)Zns+nA} zk}0bG++;PKSh0VLt|}nX$Fib3iC6eX2LLF#lBoofjf$P@;S&VI@(y;qd8wtUpIVN4 z{wxez3mKj-Sk&sY1%TPAMg9r9gVo;ZbE9_@XOw7T#J3*}!5#IHkIp4E-MKVZN8zjN zxpSsHL;(Pz1W!@tO1OtnYR{aez2hD!+DerR#iZx6kZY~qQoD@G(?Fr|c=g$`mqb=p zCKhpezsf%seEJi6ha8JsR;CtO!wF8Zz`NYXya_x4}P%8pxoYdKaP@8++gLqu@OGL zs{zE(d}{QzRY&{($T^>3rhR%#n``)>a-?>@PtNNkj-^Xhd0uaSTbxavwR=bw{ot{`!Fs%;X)rmp5r;0f$)$8Yy!Lkv4w)fxs zS$`Nfn#{2P80CIk`2rqJkQ3twqWm%tvY_Iy7HmmCEM6`fDMw>aG;;VRbh`7u6NCf4 zAQ~AEX2}Vm7dc1;9rKzyYso>0-VMY!cbeu=W>!TK7I|Dah1@@w2wIE{jeS!#{_dYC zeqLvNajC6#*}BiEY{tgrxb4L@BhEtAmX0ayhaaHT@XYOK%^rgJqSBvD0bFtdZ()@v z#mk-P2W_e$r{fr5OceBx&Z9l%-7%VeES} zFuR2`05EjIK4p=#hn;#$eX8cg3lADfsC{(3l4_a%tbFBJUTHVQhk+i+f_2`MDv9W) z$?x93E3#EqoKEnXOUC$dF2&tmwfg@|#{++V&$lm_rqftKDzUzwCt_!0Tna8q7bGze zhmdq{Ic3hXbHw^{iA0CSSG$saFU}v9lcpw%l#I&Je3cUu4+l1#L8$5k6D728r|2aP0HCBl0qR8?NIRuna)<&D!)8wJ5V*j)7a^xN_NuIdmc{sl_ zNBO>Ps(l{%0YTSD%uBF}FP&O8Cr16*sH5qxr)04+xEQhb+pd6J^qaV3Ig-&oRIC7L zzra@f)b4EApnkV%KOS2hjE#!6vpGRfCkKWDf|U zvD$rT?O$v3SmMAj9oOzGkKfX(<569C%2gLi z_}?j1*qrU2H`W-+`dB^!87%7RQkPpAHXE z_GGj4+>_wS;!y%btmSxU++Uks;a}*t9xN0 zc(m?D)BUMSn*31B`8}5L(>rI?hzYl3E$+@TC)`15_2mIo&en`K;@c=FRK=sb6yp$)PAr z03iZica@!hhv&8cq<}AR>^=vWQzV4;bpf3LW1oGNIkI8Oes9q7QC8Ydt0brXeqNYy zzRCoQNQ5Aq5FrN&J-cjQwO7kUv{+5-?V#FYmxhaHu8q9=rMEU9V@rkGfw`wDzJEp@bH~v>;i=CTEihkb|!tGq5*6#^A&r0c^+uAoTs06{cD$LvOBg((O1}Ow>lxo)IHMg`m4M znyunu z&r5GfTH9#RW^?Iiq}0cG5$L-e-2o6DY9n_hZwQJASfc3XM|-ibEKj6CFwO09+eqx4 zrt?|g)ZgH0tV8*$_*g87cGOt8xw<=eN9F+mUV|Ia9M3~f^6WORbXI@%9zeGx0D3bL zlSMqpFa1+MXXrLiDv}%F6IO9Rm_RnnU_fEw!}RuWJS$)q*240M&KTHW8R;kgtBCy^ zy&7RW@)~@zo$Pm5wuW^1#$pnU$0QITeCP81spJ)iNP1GarH#k?Yjv~wO_p~*D_CjC z>g=V}QjFN6#ay-+1yqdtxxrsSm%_k-`};CrRHAB zK}XhuSmlp{F?C+pjo(P*009tCLd>^ExsSJ82iKA2>UXs`lLRp#Orj-b|$Pl^w2;ZK*Q5F4u5A{0TJ`|$=3 z0D%MrUB07l$S}N4A&vL6j@C2AY(fvI7~hy*dPaZ1kKjYycvDp8CH-GsT8bH1p`RKw z^#DTHzy$@GV)Ur}@7d|E9hlV&&Ge!m&rw*n4#NQ&S)_wB+=4pVx}xC8ko`E7JSdilN|FOdPfFRls}unSo~?RPLlht zeaK7hHl|;Mb+oIOUn$Es+})hajxguz8f4kPHwZC8OV#s?EXKkHx4}zM`*=vk>UG^a z_-B3h)QBRy8<92FLDn%wH3?xR@*`WlclLl{GGS+d;Mlqmo8XUK%G~Vswwl=<7k|Ha zYIVn-M8`(17I#L93$2dCOh4OfT0geW^jBX$mTg_({x35PsC~U?57wyFNURh;RAFRA zE)=)qj~L}JBs3htC*2ba0NF6euW$ZT$^@Wn6bl&E!vHZXOpIhuh+rxPLL_7%5JIUW z1+0QGnki0UTY9xqw_ab1{x5qqm)Y*a`FtH}sx|rrI9Zva-if{o{0h`XcJZPM9dAg) zEIzafd#tki5P}E>01Oad7zGqygBAr!Q87!YbO?xxsSy;*u~~TXIyIu{)ny@>Lu_r3 z_N%3GgJG0w%!bc$Cr=Azl1o9%{+b-$=1wND$0gvcwjGkI59& z7!8jD0CL`#UubXJ!!lvJamDukon~-T4kM3tgxcNeXTX~kjvur%ovbz&eisRRWg8*d zc55Ofz}fKn3ZSbXVhJp2h*MP~Ei7y2U&ES&xkc1IFac?@++#exn6-onA^b$VAu4Qy zKM+9X{KNtX4Z~RvN9dv(?H!Y!;oS?+_Ioq>c1U01E4D&WIXuqR+Sc&f(ncnErmD~G zzNgpQA=_R8k=Y{~!4VRTKcY_QjXgGT)o-c$^O0Z6LzPDX)Dk+HF`yJQ(&xkh`cH&g z%l-Uy9cf?fCFU_7yFtdA(D3%m8rmpbi!1qlldeu0bPo64jk_k5i{owNTg$nHxD_@6 zm9mnOT#MfldOKcQ_L`zwO!q=FFo$pfchXr?qS-B-a{=ek zBm-Y`%#F4gm4RRMG!t5JJyL%YO>g{TNypqC+!!@pyuJgBi9ZSW+{kZdv=x`I$ zJG(F!JHrHn;zl%RL~qI_RS==pxYz2Eg$U7(=}uCSzZl~P<$R?kN4D#Wa2R#cC!ojx zI@EvUTd79aG7z*>0}e8A{+D^fLENqH1-HEY-S>0B1N=zo_L=*y=Dc1-pLu)kSQ0R7 z*F_ehcU$+-D}e4M3#62J|ilj=%0L?lRe9wjL$**Mjey!rEy)FglV!`)> zb?Y^v+B$2`{iY}h*uVf;hG^#aHe6?w9X-JBzLRgI*l`2kbUUxjl#d*=?z(4?(3_ERPVK7=30OjwgT6&}=GdKfLNB zp`<6RU_O-Y?ioVXCfA9(iGnlp3~p9tbQg$(UqKgLlR&d{q$zEIC)8&?N= zS|UV0Z~ql&K|S=j_R&tTWX-m>i<9g!^=)f27OHjNHAqPrhnUPiVpSB)*t_N7ip8hD zK!SDiPk4~Wp0Fg^unHV!XMF3Db+9+V9EDeM(k@%w9S;yH!|shjE&xWqhl9~&c~Q+} z2p~`rAgk!?FmKy-pX%RlWs!Z>OMV_M)=AnI*hanC(o`8MrRnxB9DkAI;SBk^ zf3luqvPD+uh}LK{@-P!$H1+S9U7SbsRHauu{1#jKMh%=%X{Y)4a62G?YI@|yV#jhE zOxadF@5t-M{-09aYqf=^Cj?A}b92oI56xa?7vv%>*){%p&sIv0-%=~z+Ic=q-_E+u zK(bOvFMi@R>9gss;3(2nt2RBDf;_QLt$(nCmMmWOD?j!5qeBCA8e)0f)%{G4E0}P5 zH;l%l3@Pq$TnVfP^r1;DP)Bf9BOjadyk&n*$9>ryp;)F+Qagv8)~JA=quM$3e(!7O z^F0_Jqw`iZkUmfC(d1eyo#Oa?=MNP!@%6c#62G9{U(Y}GWb7^#>0ussi|hLvXc|E{U4&VMVpE3x)H*D1^uI=W~sY{e3o)65X_1$DR{% z$SIsQrqqR#`i$JHbwPbJR~E6Iu2&cJp4**aWBrI!m+ZM5`fsg-D|WJk3B+iZ()A0a zkx=w13Y_q+b#hqM&7E`}`UGdH0a7E5=iOnQV=FglnZ}Ol*&C?Kn;*!IHg03L;)tx^ zkI#wqFe2%^Gg4qx^L)Ilj#57}Zsg@Gh|Dfnkgp@}3iX_tQY(t~8gu|;U@Z;z|&ktZf z`CUw&Si;}GR3fMhi9P;FEF$&%dUCIpP9#7OK-RNFZFN~S)AQtjAdBd3;_0JtWQtCf z{M}Vt7<(g@KKFjG;@H)8SD!U)(rV4!UbWOYq(%6xDeExsa_oI@vF-TVjQNgQSqO)G z&S8|^dH5)gYx;}pEXE|n2Lv#~5`UION+MU;BR@w0&5PqXV{)%_eTLnjNgvK6fK+>` z?%9$}Rw@-R!Dtk&`yfFZ_nc=m!;|JJP6Gpc2PsBWuu=>PQXIcrh)O{zFeN1t3PKyp z5Wu4n1YroI83{=yAPlcKFiVI~Q8|uN4WR)<3MdeSt}?V!9#_z%oGSLY_lA?Z1V-+W7nJHyVH8YFVBpVWChM7XiRMAZUl6L5JGHckUjJ zrts$eMEMcOm~Ztb!=cQ|xpSQ>ZX)3N`kf#74t{d+zHduiAY@0R)yO{R7uT0^ z>ARWaJ`_u&DE9N~YqDA9Nbx&CO)a7^-5_^UKOajMH5Jcox;34T-(^3UQJYu&uZQMg zxKfjO;#yV{Mx*@fsc~KsNsDwOqWbB3Oq#Dpq9fQr17I+M0Ss~DEU57Y^Bp9B!S?hP znfD%@s?PqNZ`Tfy-)d1g4KK35C_ooVoz~7`VM=N{L(;ls7{mvN%~-C){`b|N@6uG4+0(OKi#s9Vw!b&CT#+!vSzJ@~WO7F5Hp!iw)Ysh|Y#f=4}q$W>x zpN|E^+p_B!EQdmgtJMC-*`EXuK2TaHgh0XYsKE0jNSV95Mm2hNk(GPdNi13VcYTT! zYr5`i7d*cYh^O6(k|w$U1c{8Xfw{ua6R%eyPMxwdEM6_Ayvr}6<*11538a9K`*414 z&1Ga(Mhnw*iBqfB)_YM(!hsLZ%MRhRYrTQ|JG6Qrx#18QRey+B`a)xZ2oD%rKU&@` zZLe|ki_v*<+i*3bq4Ahqbj{bE*7#EnG;VBK&{cV3iyywfurtQ4E$F0jg@QGO!~Gaf zv3ym*;5dlH)hJ8RcDfi1=)eddFngJ?L$klBlX(9glTN8i2(5@I#N&=$4@}|ZU7AMN zRI9H|R=Kt=+rBom>(JsPVZVU>nie1KKU3BvHA7@6`y0}Kh2J`JtY*Jekaerz(b}t;!C+OM*9gX#{#_^lDWCuRW^Ron_@!-`}*y z@Z7R;U!}1`0rvEc&VFLPGY&K!`n*>aTvwPn|5>a#yYo$1*vO|oa%n-%4$LU~zujEd zPyi`@%~(A{gRwWv%6{S*Hft|P=65_G3GbOA*p=W#d$K!xg4q6!{(fzF0^%j3A@(kL zC88#S&^_8DpQ%Ho8&&;dVDIlLQ8P2@B?y;&I@ahVoDB0$jMPAd7w|_8!Mn4G87cgz zL-bF3ebe)k<<~mftAfq)Ek)pT86I%CnzXH#UnU7vou2xNSgYX_Kh#+3qy~=Qpn(sA z)Y3_IjovY4tnun+nH*I8eL|FuPMuudtVrkA}Tmx4s-kaqxR~wHV zLM)xvjGxHd*IYBJ{RIvM!L<98{=H#X-S=ebNCv#_ey?gd2AW4oDsE~{OXTRwUJZ!hWN=J@cvqa81DN37lu;=@>K27YH$M*nDvT9;- z2*~u$_Qu{VJ2$LQ&5)Gi^r+iMFQCd7;R%Di>uriwYGGa7-#B`C9HhtjZ+$I*+O_5B zd$V(l(Qczprr+TZ983TRLMAD`dsIm3MnJ=$eqR^+HVo)mfmApq?4Slo9yb6*$Im+(q|)I7~48p+eh_m!XKAlg literal 0 HcmV?d00001 diff --git a/python/tests/reference/Result/place_1.pbz2 b/python/tests/reference/Result/place_1.pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..c1963d4eaf5b3c808081454a4553c95097f00396 GIT binary patch literal 48 zcmZ>Y%CIzaj8qGbd?Z-;kb!~m!UGl{$-v~mz`~%wpxD+pi#fQkTqU@blTT56o&W$p C8Vo%E literal 0 HcmV?d00001 diff --git a/python/tests/reference/Result/place_2.pbz2 b/python/tests/reference/Result/place_2.pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..399aaaa7960d0a61c664cf1649078f8420abdb77 GIT binary patch literal 10851 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 literal 0 HcmV?d00001 diff --git a/python/tests/reference/Result/place_3.pbz2 b/python/tests/reference/Result/place_3.pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..a5fcd416861391c84cabd1e6c5841acb3c7897cb GIT binary patch literal 17373 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 C8Vo%E literal 0 HcmV?d00001 diff --git a/python/tests/reference/Result/place_6.pbz2 b/python/tests/reference/Result/place_6.pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..2844addcb207a77069e18f247a76d5a4c4a849d8 GIT binary patch literal 1269 zcmV~;-}isz{z(7-|4&zT zd*{#H72VJS*gYB9#FtveAx$++q)#IznwdQ&o|6d4rf8WB8feC*36lXbVg?D5A)v{j zpv?j?p`twqey6B30Gm;!1j(MFZ8RM{MnDZ32dE5zhz5*CLq>oAX`@CE(WXWS02n|9 zfB?|QXwU!v10VnqDMLb;rm5mJF_e0Z29HsunjWA%O{mb>Bh&x@4F-S!Gy@<9s2-z0 z4FCYp0004^05sE0G8q~)8Usxl13{2zWCKB?Kn6jPpawt~hC@v<01W^DFq&v-lR(G- zNhp!(o~N}>Q%9+z)b%uGhz$Xd9-sgRs5EE*00000&^!pwTO**;sc<)(5VxRGq~UrpnmWSOZ^R8YOBLWhZIhSWCQ3nug7RWSn9M zoD<@vdOua|tz(z*F`yI?Iisa~P{cneAkrjVz<9iTti4%GtXMb$lsQ8N4MW-MW*1>| z2-M)ySPkIo2P|kb8@E>I>tNU$@vVAQp}!mvv^rsfR=90lyyJTjtECthZH){$ZfLAr z909+*8v|t3*v{TeLxz1TunJPpD-P0w6$s9e&Fvs7J&FH&v$l$|8K3c*1wfp*MUe_H z@7-|y?q5U5dU(z?wh10mCN+WbmMYe;e%w+Fl3*t-xrk?yVpO>ZFz*L29JheshOYo& zMdBI4!YT#q#4rIHu;tqbg=G)61Dh}bf=5(EIyEZSF`HH4;&AGCL*kBhqtdYR*P{oU zpzH>|T$9w-Wa5o*dm+zv;ueQaJAc!UcHU_9_PcGJ@HaLIn{G~b$gm;nSNU!Z7Io(v z69ek}S8D~doppWNCqOMYrHR|^wvPM?N~RQH1ag#9nZZ13$v~xwNG+J)qFi2fj8?Hq zi!>`3qB~nvCIFUZd`=1BFrx{lq>F+ozH|2o!jVKNk||8o7-L(>9C5ZfjryUyEe^{&QCxCr z zV;~a%TEFP+#I4E@Py&=FfLzEAjx8>!)~zqhprnYG4%b8I{<>Qq zHI(@TDt!rMJBatdt<{Qd?#Ou#CDU-5S&Q-ui!0lna`7%ezR literal 0 HcmV?d00001 diff --git a/python/tests/reference/Result/place_7.pbz2 b/python/tests/reference/Result/place_7.pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..cab7a373946dd213f9e46d72826bbc4be968d16b GIT binary patch literal 7687 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 Bkput$ literal 0 HcmV?d00001 diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 38c2cb4ee..a175e5a94 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -401,7 +401,7 @@ class TestResult: with pytest.raises(TypeError): default.save_XDMF() - @pytest.mark.parametrize('view,labels,compress,strip', + @pytest.mark.parametrize('view,output,compress,strip', [({},['F','P','F','L_p','F_e','F_p'],True,True), ({'increments':3},'F',True,True), ({'increments':[1,8,3,4,5,6,7]},['F','P'],True,True), @@ -411,18 +411,41 @@ class TestResult: ({'phases':False},['Delta_V'],True,True), ({},['u_p','u_n'],False,False)], ids=list(range(8))) - def test_read(self,update,request,ref_path,view,labels,compress,strip): + def test_read(self,update,request,ref_path,view,output,compress,strip): result = Result(ref_path/'4grains2x4x3_compressionY.hdf5') for key,value in view.items(): result.view(key,value) N = request.node.name[8:].split('[')[1].split(']')[0] - cur = result.read(labels,compress,strip) + cur = result.read(output,compress,strip) if update: with bz2.BZ2File(ref_path/f'read_{N}.pbz2','w') as f: pickle.dump(cur,f) - + with bz2.BZ2File(ref_path/f'read_{N}.pbz2') as f: - ref = pickle.load(f) - - assert dict_equal(cur,ref) + assert dict_equal(cur,pickle.load(f)) + + + @pytest.mark.parametrize('view,output,compress,constituents,strip', + [({},['F','P','F','L_p','F_e','F_p'],True,True,None), + ({'increments':3},'F',True,True,[0,1,2,3,4,5,6,7]), + ({'increments':[1,8,3,4,5,6,7]},['F','P'],True,True,1), + ({'phases':['A','B']},['F','P'],True,True,[1,2]), + ({'phases':['A','C'],'homogenizations':False},['F','P','O'],True,True,[0,7]), + ({'phases':False,'homogenizations':False},['F','P','O'],True,True,[1,2,3,4]), + ({'phases':False},['Delta_V'],True,True,[1,2,4]), + ({},['u_p','u_n'],False,False,None)], + ids=list(range(8))) + def test_place(self,update,request,ref_path,view,output,compress,strip,constituents): + result = Result(ref_path/'4grains2x4x3_compressionY.hdf5') + for key,value in view.items(): + result.view(key,value) + + N = request.node.name[8:].split('[')[1].split(']')[0] + cur = result.place(output,compress,strip,constituents) + if update: + with bz2.BZ2File(ref_path/f'place_{N}.pbz2','w') as f: + pickle.dump(cur,f) + + with bz2.BZ2File(ref_path/f'place_{N}.pbz2') as f: + assert dict_equal(cur,pickle.load(f)) From f6d6aefe1df6b8474c1f84b2f712bdd59a3ce1f2 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Thu, 1 Apr 2021 17:33:45 -0400 Subject: [PATCH 089/219] function renaming; rewording of help messages --- python/damask/_result.py | 89 ++++++++++++++++++--------------------- python/damask/util.py | 30 ++++++++----- python/tests/test_util.py | 8 ++-- 3 files changed, 66 insertions(+), 61 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index e49c672be..3b0251c40 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -345,7 +345,7 @@ class Result: if self._allow_modification: with h5py.File(self.fname,'a') as f: for path_old in self.get_dataset_location(name_old): - path_new = os.path.join(os.path.dirname(path_old),name_new) + path_new = '/'.join([os.path.dirname(path_old),name_new]) f[path_new] = f[path_old] f[path_new].attrs['Renamed'] = f'Original name: {name_old}' if h5py3 else \ f'Original name: {name_old}'.encode() @@ -1326,25 +1326,24 @@ class Result: v.save(f'{self.fname.stem}_inc{inc[ln:].zfill(N_digits)}') - def read(self,output,compress=True,strip=True): + def read(self,output,flatten=True,prune=True): """ - Export data from file per phase/homogenization. + Export data per phase/homogenization. The returned data structure reflects the group/folder structure in the DADF5 file. Parameters ---------- - output : str or list of, optional - Name of the datasets to include. - compress : bool - Squeeze out dictionaries that are not needed for a unique - structure. This might be beneficial in the case of single - constituent or single phase simulations or if only one - time increment is considered. Defaults to 'True'. - strip : bool - Remove branches that contain no dataset. Defaults to - 'True'. + output : str or list of str + Labels of the datasets to read. + flatten : bool + Remove singular levels of the folder hierarchy. + This might be beneficial in case of a + single constituent, phase, or increment. + Defaults to True. + prune : bool + Remove branches with no data. Defaults to True. """ r = {} @@ -1365,53 +1364,49 @@ class Result: for out in output_.intersection(f['/'.join((inc,ty,label,field))].keys()): r[inc][ty][label][field][out] = _read(f,'/'.join((inc,ty,label,field,out))) - if strip: r = util.dict_strip(r) - if compress: r = util.dict_compress(r) + if prune: r = util.dict_prune(r) + if flatten: r = util.dict_flatten(r) return r - def place(self,output,compress=True,strip=True,constituents=None,fill_float=0.0,fill_int=0): + def place(self,output,flatten=True,prune=True,constituents=None,fill_float=0.0,fill_int=0): """ - Export data from file suitable sorted for spatial operations. + Export data in spatial order that is compatible with the damask.VTK geometry representation. The returned data structure reflects the group/folder structure - in the DADF5 file. In the case of multi phase simulations, the - data is merged from the individual phases/homogenizations. + in the DADF5 file. - In the cases of a single constituent and single phase simulation - this function is equivalent to `read`. + Multi-phase data is fused into a single output. + `place` is equivalent to `read` if only one phase and one constituent is present. Parameters ---------- output : str or list of, optional - Labels of the datasets to be read. - compress : bool - Squeeze out dictionaries that are not needed for a unique - structure. This might be beneficial in the case of single - phase simulations or if only one time increment is - considered. Defaults to 'True'. - strip : bool - Remove branches that contain no dataset. Defaults to - 'True'. + Labels of the datasets to place. + flatten : bool + Remove singular levels of the folder hierarchy. + This might be beneficial in case of a + single constituent, phase, or increment. + Defaults to True. + prune : bool + Remove branches with no data. Defaults to True. constituents : int or list of, optional Constituents to consider. Defaults to 'None', in which case all constituents are considered. fill_float : float - Fill value for non existent entries of floating point type. + Fill value for non-existent entries of floating point type. Defaults to 0.0. fill_int : int - Fill value for non existent entries of integer type. + Fill value for non-existent entries of integer type. Defaults to 0. """ r = {} output_ = set([output] if isinstance(output,str) else output) - if constituents is None: - constituents_ = range(self.N_constituents) - else: - constituents_ = constituents if isinstance(constituents,Iterable) else [constituents] + constituents_ = range(self.N_constituents) if constituents is None else \ + constituents if isinstance(constituents,Iterable) else [constituents] suffixes = [''] if self.N_constituents == 1 or isinstance(constituents,int) else \ [f'#{c}' for c in constituents_] @@ -1425,30 +1420,30 @@ class Result: at_cell_ph = [] in_data_ph = [] for c in range(self.N_constituents): - at_cell_ph.append({label: np.where(f[os.path.join(grp,'phase')][:,c][name] == label.encode())[0] \ + at_cell_ph.append({label: np.where(f['/'.join((grp,'phase'))][:,c][name] == label.encode())[0] \ for label in self.visible['phases']}) - in_data_ph.append({label: f[os.path.join(grp,'phase')][member][at_cell_ph[c][label]][...,c] \ + in_data_ph.append({label: f['/'.join((grp,'phase'))][member][at_cell_ph[c][label]][...,c] \ for label in self.visible['phases']}) - at_cell_ho = {label: np.where(f[os.path.join(grp,'homogenization')][:][name] == label.encode())[0] \ + at_cell_ho = {label: np.where(f['/'.join((grp,'homogenization'))][:][name] == label.encode())[0] \ for label in self.visible['homogenizations']} - in_data_ho = {label: f[os.path.join(grp,'homogenization')][member][at_cell_ho[label]] \ + in_data_ho = {label: f['/'.join((grp,'homogenization'))][member][at_cell_ho[label]] \ for label in self.visible['homogenizations']} for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{},'geometry':{}} - for out in output_.intersection(f[os.path.join(inc,'geometry')].keys()): - r[inc]['geometry'][out] = _read(f,os.path.join(inc,'geometry',out)) + for out in output_.intersection(f['/'.join((inc,'geometry'))].keys()): + r[inc]['geometry'][out] = _read(f,'/'.join((inc,'geometry',out))) for ty in ['phase','homogenization']: for label in self.visible[ty+'s']: - for field in f[os.path.join(inc,ty,label)].keys(): + for field in f['/'.join((inc,ty,label))].keys(): if field not in r[inc][ty].keys(): r[inc][ty][field] = {} - for out in output_.intersection(f[os.path.join(inc,ty,label,field)].keys()): - data = ma.array(_read(f,os.path.join(inc,ty,label,field,out))) + for out in output_.intersection(f['/'.join((inc,ty,label,field))].keys()): + data = ma.array(_read(f,'/'.join((inc,ty,label,field,out)))) if ty == 'phase': if out+suffixes[0] not in r[inc][ty][field].keys(): @@ -1472,7 +1467,7 @@ class Result: r[inc][ty][field][out][at_cell_ho[label]] = data[in_data_ho[label]] - if strip: r = util.dict_strip(r) - if compress: r = util.dict_compress(r) + if prune: r = util.dict_prune(r) + if flatten: r = util.dict_flatten(r) return r diff --git a/python/damask/util.py b/python/damask/util.py index 80d57d3dd..8e1c6a0f8 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -26,7 +26,7 @@ __all__=[ 'shapeshifter', 'shapeblender', 'extend_docstring', 'extended_docstring', 'DREAM3D_base_group', 'DREAM3D_cell_data_group', - 'dict_strip', 'dict_compress' + 'dict_prune', 'dict_flatten' ] # https://svn.blender.org/svnroot/bf-blender/trunk/blender/build_files/scons/tools/bcolors.py @@ -404,41 +404,51 @@ def DREAM3D_cell_data_group(fname): return cell_data_group -def dict_strip(d): +def dict_prune(d): """ - Remove recursively empty dictionaries. + Recursively remove empty dictionaries. Parameters ---------- d : dict - dictionary. + Dictionary to prune. + + Returns + ------- + pruned : dict + Pruned dictionary. """ # https://stackoverflow.com/questions/48151953 new = {} for k,v in d.items(): if isinstance(v, dict): - v = dict_strip(v) + v = dict_prune(v) if not isinstance(v,dict) or v != {}: new[k] = v return new -def dict_compress(d): +def dict_flatten(d): """ - Remove recursively dictionaries with one entry. + Recursively remove keys of single-entry dictionaries. Parameters ---------- d : dict - dictionary. + Dictionary to flatten. + + Returns + ------- + flattened : dict + Flattened dictionary. """ if isinstance(d,dict) and len(d) == 1: entry = d[list(d.keys())[0]] - new = dict_compress(entry.copy()) if isinstance(entry,dict) else entry + new = dict_flatten(entry.copy()) if isinstance(entry,dict) else entry else: - new = {k: (dict_compress(v) if isinstance(v, dict) else v) for k,v in d.items()} + new = {k: (dict_flatten(v) if isinstance(v, dict) else v) for k,v in d.items()} return new diff --git a/python/tests/test_util.py b/python/tests/test_util.py index 500e7d733..3ed3bf908 100644 --- a/python/tests/test_util.py +++ b/python/tests/test_util.py @@ -143,8 +143,8 @@ class TestUtil: ({'A':{'B':{}}}, {}), ({'A':{'B':'C'}},)*2, ({'A':{'B':{},'C':'D'}}, {'A':{'C':'D'}})]) - def test_strip(self,full,reduced): - assert util.dict_strip(full) == reduced + def test_prune(self,full,reduced): + assert util.dict_prune(full) == reduced @pytest.mark.parametrize('full,reduced',[({}, {}), @@ -156,5 +156,5 @@ class TestUtil: ({'A':{'B':'C','D':'E'}}, {'B':'C','D':'E'}), ({'B':'C','D':'E'},)*2, ({'A':{'B':{},'C':'D'}}, {'B':{},'C':'D'})]) - def test_compress(self,full,reduced): - assert util.dict_compress(full) == reduced + def test_flatten(self,full,reduced): + assert util.dict_flatten(full) == reduced From 9459fea92932ce4178aebc45145a1c9e915e6163 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 1 Apr 2021 17:29:12 +0200 Subject: [PATCH 090/219] support for pandas not planned any more damask.Table supports multidimensional data, numpy.ma supports masked arrays --- python/damask/_vtk.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index ebd2f39a6..a5fc43dfa 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -2,7 +2,6 @@ import os import multiprocessing as mp from pathlib import Path -import pandas as pd import numpy as np import vtk from vtk.util.numpy_support import numpy_to_vtk as np_to_vtk @@ -224,7 +223,7 @@ class VTK: # Check https://blog.kitware.com/ghost-and-blanking-visibility-changes/ for missing data - # Needs support for pd.DataFrame and/or table + # Needs support for damask.Table def add(self,data,label=None): """ Add data to either cells or points. @@ -256,8 +255,6 @@ class VTK: self.vtk_data.GetCellData().AddArray(d) else: raise ValueError(f'Cell / point count ({N_cells} / {N_points}) differs from data ({N_data}).') - elif isinstance(data,pd.DataFrame): - raise NotImplementedError('pd.DataFrame') elif isinstance(data,Table): raise NotImplementedError('damask.Table') else: From 58ac99831cb9f66d284ed6da120fb15c30c11147 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 2 Apr 2021 07:47:03 +0200 Subject: [PATCH 091/219] polishing --- python/damask/_result.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 3b0251c40..7f508d2df 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1405,8 +1405,8 @@ class Result: r = {} output_ = set([output] if isinstance(output,str) else output) - constituents_ = range(self.N_constituents) if constituents is None else \ - constituents if isinstance(constituents,Iterable) else [constituents] + constituents_ = constituents if isinstance(constituents,Iterable) else \ + (range(self.N_constituents) if constituents is None else [constituents]) suffixes = [''] if self.N_constituents == 1 or isinstance(constituents,int) else \ [f'#{c}' for c in constituents_] @@ -1422,7 +1422,7 @@ class Result: for c in range(self.N_constituents): at_cell_ph.append({label: np.where(f['/'.join((grp,'phase'))][:,c][name] == label.encode())[0] \ for label in self.visible['phases']}) - in_data_ph.append({label: f['/'.join((grp,'phase'))][member][at_cell_ph[c][label]][...,c] \ + in_data_ph.append({label: f['/'.join((grp,'phase'))][member][at_cell_ph[c][label]][:,c] \ for label in self.visible['phases']}) at_cell_ho = {label: np.where(f['/'.join((grp,'homogenization'))][:][name] == label.encode())[0] \ @@ -1450,7 +1450,7 @@ class Result: container = np.empty((self.N_materialpoints,)+data.shape[1:],dtype=data.dtype) fill_value = fill_float if data.dtype in np.sctypes['float'] else \ fill_int - for c,suffix in zip(constituents_, suffixes): + for c,suffix in zip(constituents_,suffixes): r[inc][ty][field][out+suffix] = \ ma.array(container,fill_value=fill_value,mask=True) From cf1ce6a1fe7a9e143f22dce7b348ca02911e2934 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 2 Apr 2021 08:07:22 +0200 Subject: [PATCH 092/219] support for masked array masked arrays are the outcome of Result.place --- python/damask/_vtk.py | 9 ++++++--- python/tests/test_VTK.py | 10 ++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index a5fc43dfa..340bd1ea3 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -3,6 +3,7 @@ import multiprocessing as mp from pathlib import Path import numpy as np +import numpy.ma as ma import vtk from vtk.util.numpy_support import numpy_to_vtk as np_to_vtk from vtk.util.numpy_support import numpy_to_vtkIdTypeArray as np_to_vtkIdTypeArray @@ -230,7 +231,7 @@ class VTK: Parameters ---------- - data : numpy.ndarray + data : numpy.ndarray or numpy.ma.MaskedArray Data to add. First dimension needs to match either number of cells or number of points. label : str @@ -245,8 +246,10 @@ class VTK: raise ValueError('No label defined for numpy.ndarray') N_data = data.shape[0] - d = np_to_vtk((data.astype(np.single) if data.dtype in [np.double, np.longdouble] else - data).reshape(N_data,-1),deep=True) # avoid large files + data_ = np.where(data.mask,data.fill_value,data) if isinstance(data,ma.MaskedArray) else\ + data + d = np_to_vtk((data_.astype(np.single) if data_.dtype in [np.double, np.longdouble] else + data_).reshape(N_data,-1),deep=True) # avoid large files d.SetName(label) if N_data == N_points: diff --git a/python/tests/test_VTK.py b/python/tests/test_VTK.py index a3cba354f..4328dc810 100644 --- a/python/tests/test_VTK.py +++ b/python/tests/test_VTK.py @@ -4,6 +4,7 @@ import time import pytest import numpy as np +import numpy.ma as ma from damask import VTK from damask import grid_filters @@ -134,6 +135,15 @@ class TestVTK: with pytest.raises(TypeError): default.add('invalid_type','valid') + def test_add_masked(self,default): + data = np.random.rand(5*6*7,3) + masked = ma.MaskedArray(data,mask=data<.4,fill_value=42.) + default.add(masked,'D') + result_masked = str(default) + default.add(np.where(masked.mask,masked.fill_value,masked),'D') + assert result_masked == str(default) + + def test_comments(self,tmp_path,default): default.add_comments(['this is a comment']) default.save(tmp_path/'with_comments',parallel=False) From 18afa217fe0cffa8d186f16561ef5f5d7ff15678 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 2 Apr 2021 08:24:49 +0200 Subject: [PATCH 093/219] easier to understand limit to same fields for homogenization and fields results in a little less flexibility (requires two views) but should be acceptable for such a little used feature --- python/damask/_result.py | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 7f508d2df..65eb66064 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -84,21 +84,17 @@ class Result: self.phases = [c.decode() for c in np.unique(f[f'{grp}/phase'] ['Name' if self.version_minor < 12 else 'label'])] - self.out_type_ph = [] + self.fields = [] for c in self.phases: - self.out_type_ph += f['/'.join([self.increments[0],'phase',c])].keys() - self.out_type_ph = list(set(self.out_type_ph)) # make unique - - self.out_type_ho = [] + self.fields += f['/'.join([self.increments[0],'phase',c])].keys() for m in self.homogenizations: - self.out_type_ho += f['/'.join([self.increments[0],'homogenization',m])].keys() - self.out_type_ho = list(set(self.out_type_ho)) # make unique + self.fields += f['/'.join([self.increments[0],'homogenization',m])].keys() + self.fields = list(set(self.fields)) # make unique self.visible = {'increments': self.increments, 'phases': self.phases, 'homogenizations': self.homogenizations, - 'out_type_ph': self.out_type_ph, - 'out_type_ho': self.out_type_ho + 'fields': self.fields, } self.fname = Path(fname).absolute() @@ -392,7 +388,7 @@ class Result: with h5py.File(self.fname,'r') as f: for i in self.iterate('increments'): - for o,p in zip(['phases','homogenizations'],['out_type_ph','out_type_ho']): + for o,p in zip(['phases','homogenizations'],['fields','fields']): for oo in self.iterate(o): for pp in self.iterate(p): group = '/'.join([i,o[:-1],oo,pp]) # o[:-1]: plural/singular issue @@ -414,7 +410,7 @@ class Result: with h5py.File(self.fname,'r') as f: for i in self.iterate('increments'): message += f'\n{i} ({self.times[self.increments.index(i)]}s)\n' - for o,p in zip(['phases','homogenizations'],['out_type_ph','out_type_ho']): + for o,p in zip(['phases','homogenizations'],['fields','fields']): message += f' {o[:-1]}\n' for oo in self.iterate(o): message += f' {oo}\n' @@ -448,7 +444,7 @@ class Result: path.append(k) except KeyError: pass - for o,p in zip(['phases','homogenizations'],['out_type_ph','out_type_ho']): + for o,p in zip(['phases','homogenizations'],['fields','fields']): for oo in self.iterate(o): for pp in self.iterate(p): k = '/'.join([i,o[:-1],oo,pp,label]) @@ -1222,7 +1218,7 @@ class Result: 'Dimensions': '{} {} {} 3'.format(*(self.cells+1))} data_items[-1].text=f'{os.path.split(self.fname)[1]}:/{inc}/geometry/u_n' - for o,p in zip(['phases','homogenizations'],['out_type_ph','out_type_ho']): + for o,p in zip(['phases','homogenizations'],['fields','fields']): for oo in getattr(self,o): for pp in getattr(self,p): g = '/'.join([inc,o[:-1],oo,pp]) @@ -1286,7 +1282,7 @@ class Result: viewed_backup_ho = self.visible['homogenizations'].copy() self.view('homogenizations',False) for label in (labels if isinstance(labels,list) else [labels]): - for o in self.iterate('out_type_ph'): + for o in self.iterate('fields'): for c in range(self.N_constituents): prefix = '' if self.N_constituents == 1 else f'constituent{c}/' if o not in ['mechanics', 'mechanical']: # compatibility hack @@ -1312,7 +1308,7 @@ class Result: viewed_backup_ph = self.visible['phases'].copy() self.view('phases',False) for label in (labels if isinstance(labels,list) else [labels]): - for _ in self.iterate('out_type_ho'): + for _ in self.iterate('fields'): paths = self.get_dataset_location(label) if len(paths) == 0: continue From e8ff5095020ee3b1f87d45a3f70cf021d44c0747 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 2 Apr 2021 08:56:14 +0200 Subject: [PATCH 094/219] output all datasets per default respect 'field' selection --- python/damask/_result.py | 59 +++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 65eb66064..14f800991 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -25,10 +25,10 @@ from . import util h5py3 = h5py.__version__[0] == '3' -def _read(handle,path): - metadata = {k:(v if h5py3 else v.decode()) for k,v in handle[path].attrs.items()} - dtype = np.dtype(handle[path].dtype,metadata=metadata) - return np.array(handle[path],dtype=dtype) +def _read(dataset): + metadata = {k:(v if h5py3 else v.decode()) for k,v in dataset.attrs.items()} + dtype = np.dtype(dataset.dtype,metadata=metadata) + return np.array(dataset,dtype=dtype) class Result: @@ -1274,7 +1274,6 @@ class Result: # compatibility hack ln = 3 if self.version_minor < 12 else 10 - N_digits = int(np.floor(np.log10(max(1,int(self.increments[-1][ln:])))))+1 for inc in util.show_progress(self.iterate('increments'),len(self.visible['increments'])): @@ -1322,7 +1321,7 @@ class Result: v.save(f'{self.fname.stem}_inc{inc[ln:].zfill(N_digits)}') - def read(self,output,flatten=True,prune=True): + def read(self,output='*',flatten=True,prune=True): """ Export data per phase/homogenization. @@ -1332,12 +1331,12 @@ class Result: Parameters ---------- output : str or list of str - Labels of the datasets to read. + Labels of the datasets to read. Defaults to '*', in which + case all datasets are placed. flatten : bool Remove singular levels of the folder hierarchy. - This might be beneficial in case of a - single constituent, phase, or increment. - Defaults to True. + This might be beneficial in case of single increment, + phase/homogenization, or field. Defaults to True. prune : bool Remove branches with no data. Defaults to True. @@ -1349,16 +1348,18 @@ class Result: for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{},'geometry':{}} - for out in output_.intersection(f['/'.join((inc,'geometry'))].keys()): - r[inc]['geometry'][out] = _read(f,'/'.join((inc,'geometry',out))) + for out in f['/'.join((inc,'geometry'))].keys() if '*' in output_ else \ + output_.intersection(f['/'.join((inc,'geometry'))].keys()): + r[inc]['geometry'][out] = _read(f['/'.join((inc,'geometry',out))]) for ty in ['phase','homogenization']: for label in self.visible[ty+'s']: r[inc][ty][label] = {} - for field in f['/'.join((inc,ty,label))].keys(): + for field in set(self.visible['fields']).union(f['/'.join((inc,ty,label))].keys()): r[inc][ty][label][field] = {} - for out in output_.intersection(f['/'.join((inc,ty,label,field))].keys()): - r[inc][ty][label][field][out] = _read(f,'/'.join((inc,ty,label,field,out))) + for out in f['/'.join((inc,ty,label,field))].keys() if '*' in output_ else \ + output_.intersection(f['/'.join((inc,ty,label,field))].keys()): + r[inc][ty][label][field][out] = _read(f['/'.join((inc,ty,label,field,out))]) if prune: r = util.dict_prune(r) if flatten: r = util.dict_flatten(r) @@ -1366,7 +1367,7 @@ class Result: return r - def place(self,output,flatten=True,prune=True,constituents=None,fill_float=0.0,fill_int=0): + def place(self,output='*',flatten=True,prune=True,constituents=None,fill_float=0.0,fill_int=0): """ Export data in spatial order that is compatible with the damask.VTK geometry representation. @@ -1379,12 +1380,12 @@ class Result: Parameters ---------- output : str or list of, optional - Labels of the datasets to place. + Labels of the datasets to place. Defaults to '*', in which + case all datasets are placed. flatten : bool Remove singular levels of the folder hierarchy. - This might be beneficial in case of a - single constituent, phase, or increment. - Defaults to True. + This might be beneficial in case of single increment + or field. Defaults to True. prune : bool Remove branches with no data. Defaults to True. constituents : int or list of, optional @@ -1429,33 +1430,35 @@ class Result: for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{},'geometry':{}} - for out in output_.intersection(f['/'.join((inc,'geometry'))].keys()): - r[inc]['geometry'][out] = _read(f,'/'.join((inc,'geometry',out))) + for out in f['/'.join((inc,'geometry'))].keys() if '*' in output_ else \ + output_.intersection(f['/'.join((inc,'geometry'))].keys()): + r[inc]['geometry'][out] = _read(f['/'.join((inc,'geometry',out))]) for ty in ['phase','homogenization']: for label in self.visible[ty+'s']: - for field in f['/'.join((inc,ty,label))].keys(): + for field in set(self.visible['fields']).union(f['/'.join((inc,ty,label))].keys()): if field not in r[inc][ty].keys(): r[inc][ty][field] = {} - for out in output_.intersection(f['/'.join((inc,ty,label,field))].keys()): - data = ma.array(_read(f,'/'.join((inc,ty,label,field,out)))) + for out in f['/'.join((inc,ty,label,field))].keys() if '*' in output_ else \ + output_.intersection(f['/'.join((inc,ty,label,field))].keys()): + data = ma.array(_read(f['/'.join((inc,ty,label,field,out))])) if ty == 'phase': if out+suffixes[0] not in r[inc][ty][field].keys(): - container = np.empty((self.N_materialpoints,)+data.shape[1:],dtype=data.dtype) + container = np.empty((self.N_materialpoints,)+data.shape[1:],data.dtype) fill_value = fill_float if data.dtype in np.sctypes['float'] else \ fill_int for c,suffix in zip(constituents_,suffixes): r[inc][ty][field][out+suffix] = \ ma.array(container,fill_value=fill_value,mask=True) - for c,suffix in zip(constituents_, suffixes): + for c,suffix in zip(constituents_,suffixes): r[inc][ty][field][out+suffix][at_cell_ph[c][label]] = data[in_data_ph[c][label]] if ty == 'homogenization': if out not in r[inc][ty][field].keys(): - container = np.empty((self.N_materialpoints,)+data.shape[1:],dtype=data.dtype) + container = np.empty((self.N_materialpoints,)+data.shape[1:],data.dtype) fill_value = fill_float if data.dtype in np.sctypes['float'] else \ fill_int r[inc][ty][field][out] = \ From 20d0242d59a2aad1e0bb8f69ff2cbe9c39697195 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 2 Apr 2021 12:21:27 +0200 Subject: [PATCH 095/219] using new logic --- python/damask/_result.py | 130 +++++++++++++++++++++++------------- python/tests/test_Result.py | 2 +- 2 files changed, 83 insertions(+), 49 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 14f800991..78f30bc3b 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1246,17 +1246,27 @@ class Result: f.write(xml.dom.minidom.parseString(ET.tostring(xdmf).decode()).toprettyxml()) - def save_VTK(self,labels=[],mode='cell'): + def save_VTK(self,output='*',mode='cell',constituents=None,fill_float=np.nan,fill_int=0): """ Export to vtk cell/point data. Parameters ---------- - labels : str or list of, optional - Labels of the datasets to be exported. + output : str or list of, optional + Labels of the datasets to place. Defaults to '*', in which + case all datasets are exported. mode : str, either 'cell' or 'point' Export in cell format or point format. Defaults to 'cell'. + constituents : int or list of, optional + Constituents to consider. Defaults to 'None', in which case + all constituents are considered. + fill_float : float + Fill value for non-existent entries of floating point type. + Defaults to 0.0. + fill_int : int + Fill value for non-existent entries of integer type. + Defaults to 0. """ if mode.lower()=='cell': @@ -1272,53 +1282,76 @@ class Result: elif mode.lower()=='point': v = VTK.from_poly_data(self.coordinates0_point) - # compatibility hack - ln = 3 if self.version_minor < 12 else 10 + ln = 3 if self.version_minor < 12 else 10 # compatibility hack N_digits = int(np.floor(np.log10(max(1,int(self.increments[-1][ln:])))))+1 - for inc in util.show_progress(self.iterate('increments'),len(self.visible['increments'])): + output_ = set([output] if isinstance(output,str) else output) + constituents_ = constituents if isinstance(constituents,Iterable) else \ + (range(self.N_constituents) if constituents is None else [constituents]) - viewed_backup_ho = self.visible['homogenizations'].copy() - self.view('homogenizations',False) - for label in (labels if isinstance(labels,list) else [labels]): - for o in self.iterate('fields'): - for c in range(self.N_constituents): - prefix = '' if self.N_constituents == 1 else f'constituent{c}/' - if o not in ['mechanics', 'mechanical']: # compatibility hack - for _ in self.iterate('phases'): - path = self.get_dataset_location(label) - if len(path) == 0: - continue - array = self.read_dataset(path,c) - v.add(array,prefix+path[0].split('/',1)[1]+f' / {self._get_attribute(path[0],"unit")}') - else: - paths = self.get_dataset_location(label) - if len(paths) == 0: - continue - array = self.read_dataset(paths,c) - if self.version_minor < 12: - ph_name = re.compile(r'(?<=(phase\/))(.*?)(?=(mechanics))') # identify phase name - else: - ph_name = re.compile(r'(?<=(phase\/))(.*?)(?=(mechanical))') # identify phase name - dset_name = prefix+re.sub(ph_name,r'',paths[0].split('/',1)[1]) # remove phase name - v.add(array,dset_name+f' / {self._get_attribute(paths[0],"unit")}') - self.view('homogenizations',viewed_backup_ho) + suffixes = [''] if self.N_constituents == 1 or isinstance(constituents,int) else \ + [f'#{c}' for c in constituents_] - viewed_backup_ph = self.visible['phases'].copy() - self.view('phases',False) - for label in (labels if isinstance(labels,list) else [labels]): - for _ in self.iterate('fields'): - paths = self.get_dataset_location(label) - if len(paths) == 0: - continue - array = self.read_dataset(paths) - v.add(array,paths[0].split('/',1)[1]+f' / {self._get_attribute(paths[0],"unit")}') - self.view('phases',viewed_backup_ph) + grp = 'mapping' if self.version_minor < 12 else 'cell_to' # compatibility hack + name = 'Name' if self.version_minor < 12 else 'label' # compatibility hack + member = 'member' if self.version_minor < 12 else 'entry' # compatibility hack - u = self.read_dataset(self.get_dataset_location('u_n' if mode.lower() == 'cell' else 'u_p')) - v.add(u,'u') + with h5py.File(self.fname,'r') as f: - v.save(f'{self.fname.stem}_inc{inc[ln:].zfill(N_digits)}') + at_cell_ph = [] + in_data_ph = [] + for c in range(self.N_constituents): + at_cell_ph.append({label: np.where(f['/'.join((grp,'phase'))][:,c][name] == label.encode())[0] \ + for label in self.visible['phases']}) + in_data_ph.append({label: f['/'.join((grp,'phase'))][member][at_cell_ph[c][label]][:,c] \ + for label in self.visible['phases']}) + + at_cell_ho = {label: np.where(f['/'.join((grp,'homogenization'))][:][name] == label.encode())[0] \ + for label in self.visible['homogenizations']} + in_data_ho = {label: f['/'.join((grp,'homogenization'))][member][at_cell_ho[label]] \ + for label in self.visible['homogenizations']} + + for inc in util.show_progress(self.visible['increments']): + + u = _read(f['/'.join((inc,'geometry','u_n' if mode.lower() == 'cell' else 'u_p'))]) + v.add(u,'u') + + for ty in ['phase','homogenization']: + for field in self.visible['fields']: + for label in self.visible[ty+'s']: + if field not in f['/'.join((inc,ty,label))].keys(): continue + outs = {} + + for out in f['/'.join((inc,ty,label,field))].keys() if '*' in output_ else \ + output_.intersection(f['/'.join((inc,ty,label,field))].keys()): + data = ma.array(_read(f['/'.join((inc,ty,label,field,out))])) + + if ty == 'phase': + if out+suffixes[0] not in outs.keys(): + container = np.empty((self.N_materialpoints,)+data.shape[1:],data.dtype) + fill_value = fill_float if data.dtype in np.sctypes['float'] else \ + fill_int + for c,suffix in zip(constituents_,suffixes): + outs[out+suffix] = \ + ma.array(container,fill_value=fill_value,mask=True) + + for c,suffix in zip(constituents_,suffixes): + outs[out+suffix][at_cell_ph[c][label]] = data[in_data_ph[c][label]] + + if ty == 'homogenization': + if out not in outs.keys(): + container = np.empty((self.N_materialpoints,)+data.shape[1:],data.dtype) + fill_value = fill_float if data.dtype in np.sctypes['float'] else \ + fill_int + outs[out] = \ + ma.array(container,fill_value=fill_value,mask=True) + + outs[out][at_cell_ho[label]] = data[in_data_ho[label]] + + for label,dataset in outs.items(): + v.add(dataset,' / '.join(('/'.join((ty,field,label)),dataset.dtype.metadata['unit']))) + + v.save(f'{self.fname.stem}_inc{inc[ln:].zfill(N_digits)}') def read(self,output='*',flatten=True,prune=True): @@ -1375,7 +1408,8 @@ class Result: in the DADF5 file. Multi-phase data is fused into a single output. - `place` is equivalent to `read` if only one phase and one constituent is present. + `place` is equivalent to `read` if only one phase/homogenization + and one constituent is present. Parameters ---------- @@ -1408,9 +1442,9 @@ class Result: suffixes = [''] if self.N_constituents == 1 or isinstance(constituents,int) else \ [f'#{c}' for c in constituents_] - grp = 'mapping' if self.version_minor < 12 else 'cell_to' - name = 'Name' if self.version_minor < 12 else 'label' - member = 'member' if self.version_minor < 12 else 'entry' + grp = 'mapping' if self.version_minor < 12 else 'cell_to' # compatibility hack + name = 'Name' if self.version_minor < 12 else 'label' # compatibility hack + member = 'member' if self.version_minor < 12 else 'entry' # compatibility hack with h5py.File(self.fname,'r') as f: diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index a175e5a94..0d66f8cd5 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -376,7 +376,7 @@ class TestResult: b = default.coordinates0_node.reshape(tuple(default.cells+1)+(3,),order='F') assert np.allclose(a,b) - @pytest.mark.parametrize('output',['F',[],['F','P']]) + @pytest.mark.parametrize('output',['F','*',['F','P']]) def test_vtk(self,tmp_path,default,output): os.chdir(tmp_path) default.save_VTK(output) From 1b2d892b423ed2c6cb0806b5e2b2e679d20b738a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 3 Apr 2021 07:31:31 +0200 Subject: [PATCH 096/219] keep reference folder clean --- .../reference/Result/place/test_place[0].pbz2 | Bin 0 -> 41307 bytes .../test_place[1].pbz2} | Bin .../reference/Result/place/test_place[2].pbz2 | Bin 0 -> 10037 bytes .../reference/Result/place/test_place[3].pbz2 | Bin 0 -> 16847 bytes .../reference/Result/place/test_place[4].pbz2 | Bin 0 -> 8840 bytes .../test_place[5].pbz2} | Bin .../test_place[6].pbz2} | Bin .../reference/Result/place/test_place[7].pbz2 | Bin 0 -> 7681 bytes python/tests/reference/Result/place_0.pbz2 | Bin 40927 -> 0 bytes python/tests/reference/Result/place_2.pbz2 | Bin 10851 -> 0 bytes python/tests/reference/Result/place_3.pbz2 | Bin 17373 -> 0 bytes python/tests/reference/Result/place_4.pbz2 | Bin 8573 -> 0 bytes python/tests/reference/Result/place_7.pbz2 | Bin 7687 -> 0 bytes .../reference/Result/read/test_read[0].pbz2 | Bin 0 -> 286602 bytes .../{read_1.pbz2 => read/test_read[1].pbz2} | Bin .../{read_2.pbz2 => read/test_read[2].pbz2} | Bin .../{read_3.pbz2 => read/test_read[3].pbz2} | Bin .../{read_4.pbz2 => read/test_read[4].pbz2} | Bin .../{read_5.pbz2 => read/test_read[5].pbz2} | Bin .../{read_6.pbz2 => read/test_read[6].pbz2} | Bin .../reference/Result/read/test_read[7].pbz2 | Bin 0 -> 7762 bytes python/tests/reference/Result/read_0.pbz2 | Bin 286579 -> 0 bytes python/tests/reference/Result/read_7.pbz2 | Bin 7734 -> 0 bytes .../Result/save_VTK/test_vtk[0-0-0].md5 | 1 + .../Result/save_VTK/test_vtk[0-0-1].md5 | 1 + .../Result/save_VTK/test_vtk[0-0-2].md5 | 1 + .../Result/save_VTK/test_vtk[1-0-0].md5 | 1 + .../Result/save_VTK/test_vtk[1-0-1].md5 | 1 + .../Result/save_VTK/test_vtk[1-0-2].md5 | 1 + python/tests/test_Result.py | 40 ++++++++++++++---- 30 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 python/tests/reference/Result/place/test_place[0].pbz2 rename python/tests/reference/Result/{place_1.pbz2 => place/test_place[1].pbz2} (100%) create mode 100644 python/tests/reference/Result/place/test_place[2].pbz2 create mode 100644 python/tests/reference/Result/place/test_place[3].pbz2 create mode 100644 python/tests/reference/Result/place/test_place[4].pbz2 rename python/tests/reference/Result/{place_5.pbz2 => place/test_place[5].pbz2} (100%) rename python/tests/reference/Result/{place_6.pbz2 => place/test_place[6].pbz2} (100%) create mode 100644 python/tests/reference/Result/place/test_place[7].pbz2 delete mode 100644 python/tests/reference/Result/place_0.pbz2 delete mode 100644 python/tests/reference/Result/place_2.pbz2 delete mode 100644 python/tests/reference/Result/place_3.pbz2 delete mode 100644 python/tests/reference/Result/place_4.pbz2 delete mode 100644 python/tests/reference/Result/place_7.pbz2 create mode 100644 python/tests/reference/Result/read/test_read[0].pbz2 rename python/tests/reference/Result/{read_1.pbz2 => read/test_read[1].pbz2} (100%) rename python/tests/reference/Result/{read_2.pbz2 => read/test_read[2].pbz2} (100%) rename python/tests/reference/Result/{read_3.pbz2 => read/test_read[3].pbz2} (100%) rename python/tests/reference/Result/{read_4.pbz2 => read/test_read[4].pbz2} (100%) rename python/tests/reference/Result/{read_5.pbz2 => read/test_read[5].pbz2} (100%) rename python/tests/reference/Result/{read_6.pbz2 => read/test_read[6].pbz2} (100%) create mode 100644 python/tests/reference/Result/read/test_read[7].pbz2 delete mode 100644 python/tests/reference/Result/read_0.pbz2 delete mode 100644 python/tests/reference/Result/read_7.pbz2 create mode 100644 python/tests/reference/Result/save_VTK/test_vtk[0-0-0].md5 create mode 100644 python/tests/reference/Result/save_VTK/test_vtk[0-0-1].md5 create mode 100644 python/tests/reference/Result/save_VTK/test_vtk[0-0-2].md5 create mode 100644 python/tests/reference/Result/save_VTK/test_vtk[1-0-0].md5 create mode 100644 python/tests/reference/Result/save_VTK/test_vtk[1-0-1].md5 create mode 100644 python/tests/reference/Result/save_VTK/test_vtk[1-0-2].md5 diff --git a/python/tests/reference/Result/place/test_place[0].pbz2 b/python/tests/reference/Result/place/test_place[0].pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..2d1d432b9ad9668be488a887053dc1558bf7cb36 GIT binary patch literal 41307 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%0AjdEMKpq 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�E9j7hf7x$>0ls$vgLe6A%&FPhh~q_ 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 ncL~Sd4x4+)U+2}p&re%PBf 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 K3KANKqkQ0o;6B&@ literal 0 HcmV?d00001 diff --git a/python/tests/reference/Result/place_5.pbz2 b/python/tests/reference/Result/place/test_place[5].pbz2 similarity index 100% rename from python/tests/reference/Result/place_5.pbz2 rename to python/tests/reference/Result/place/test_place[5].pbz2 diff --git a/python/tests/reference/Result/place_6.pbz2 b/python/tests/reference/Result/place/test_place[6].pbz2 similarity index 100% rename from python/tests/reference/Result/place_6.pbz2 rename to python/tests/reference/Result/place/test_place[6].pbz2 diff --git a/python/tests/reference/Result/place/test_place[7].pbz2 b/python/tests/reference/Result/place/test_place[7].pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..cd4f098a1bd150746a0aee39d826806b26c6d2cd GIT binary patch literal 7681 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 literal 0 HcmV?d00001 diff --git a/python/tests/reference/Result/place_0.pbz2 b/python/tests/reference/Result/place_0.pbz2 deleted file mode 100644 index e8a7d1399d3fd9d44c753476660ea67d32fe869b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40927 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 w zML9}2-vK55Ds8(r;Y`R9Y?T>1+nY{$tl`V4tjaWbrwxJ#Af|a3k7o|jw71D{s~rOL z>OvZ#SnlX)#=oMO#T8hvkK6ibYJQ=ws+v`w1ncUQvYFJ(ZynNI{z8}xt`D$Z4vi@$5W397x)at*d(0<=2J6ntRI9V1J z1PpjWNpEUcKY$qDWAro&hgilIsqHqrf)CpiOB#U0IMzgAOZwhU1dipBhQRz3TQv4nVDVcU)cV@ZeWx7 zUS4-xT8vwWbE!V*N1j0`%yJb!SUxr`iZLkB0bzael_`73bahr0GH$TePPCf<(chCl zGltWy_AK02m8Wd328%+M#y_)DyFV)y9Ocq6_SZx4CmoqTRROSC=S$q&P-=|2*d252 z8&~qmf>({<#WUKpQj`tKgDHC6G>crk;+-D=b_f8}ob4<4JFXA}p8i2V@WEZTv2aOP z5E%=*KwC5oD{o^mhSr~VqdU|r0D=gWcIJc}J^7;Kx>1I^di4aT7HQq+rb>%S0D;Q8 zMpve>n(-3EzEskJDT8#-9O6Y6I`vxU+0ZfEx~gxQzj3IlMVU2fGplFDmVmS(jkc@u zirPU<xOJ~A{W+CqJMX)UI)$NhS*72}wU<4kIpt421R)9{1VkVp z&8AONT8_3ywn?UhIz{?g+cnVvm5Uu1|#0!Zt<6!eju?aZaRIBQxOXlyQffmVDj(YswDw7eVdsA zyt%i%Ctrn!@pw3$rGpi^{l-}F`OvGSdPH8U9rt>x1|}R4005PkthcyDXyP4xApr*U zg=b`+9^(;Xy!d=l^jfdNr}uDL>_=7g8Lb)csSjRgEv?QK zMCXU{1O*C=mx1(hV^YwhK=VWYoc6Rr12lD{Dubtl?Vw3GbmytLj~DRK1pMhO zeXQY1X93l)3n}-42K@uKXZbf!Fd#u3*ls0z{x1cpZZwkE{IMqIEK5G~*>kEGE$yCC zV7{kntTpN`sW{jG)c7hwU6n8KU6E~pa}44*)W;9i(lwF1|8sa-ousy+wdB}&myzfE z78C>2cwtre)BQ_N2&V0&!n(qbIEmsU;gZD#{n>Ph>*b_**Cyx-P$2w5(GEzi{hHI; zwzIysA?Zo^J7`VlYf~J5HgWC){YxtD{rvy2-l(x|*^a!F9&nuE#xY@0i}&M))PE0& zCP(`x6ODWX#0@I|JCC6Q)f@q>lVTVBAM%L_$aMk+`JS<1zX!)~-i=D=P$Pf<+rIN| z^UHs#AKkz6O~dV+si&N9tv6lXqQw@G9j0P1bR0A{&Y)A|B#?k_x!8V|QyPE6YkpeE zLT1)1qxJ3-+VGo^YZ=svZ^rh>uh?O+>_kXNX34?U* zIt-!C+aoY*F=S6i!IEJ8`{ps{Xt~)Z_gd97=1lTy?(}Iw^ZctGM&j+M{pNGYFUR;e zFHe1dbMhzUv#2smG~f&_R$0isBoTVIgsn7zR?4lWN02GY5)N%v=B z)a{pDS@V+DR%5~h5ZZyPe_QlACHw8M|9V4|$f=G_xWn?T52`yY9CuS1g{0xt@BHiI zRjC<9M9ZcuW~DxxqkChwca-M}%G1=+to;F(*zq+su8jND%#HyFDuE`Rh>POr0&%o& ztYhai&73sL`clWapUN#+3$JF) zLIH8{3tkG{+TpKy0nYzO8KQPq(dfOWnKE-i+z+RVhU4Ih0I`<82uSQ3jGyC-0i;eG@7wV#j^<7=vEc%fHnv}dTJWnJ9xkk;> zSO!Gv2L5U3n1y`$qDSDc@KleAU^(8$9s!+zL$ydzWBbmLNTNk$rYNjsvgtWHSGLyv zNMvMwDRiGp7gmKlH)G;ITpw|{)A3!)n*h=Jj&tQ-wro6Tnm{8i zhxIv?fmjX(A-wI14luK-!~|S9rjk7mCekWC*+nIv;X66+59A216=Z~_<655#m)mk@ zteQokEKydSNYXL5lc6VM=eRNs^!Bgf`C73#;?Ho^D21c+6@%W{>y7r{Pfe6{8!jAn zK6>D^9rPmYI4hlX3F9BH+tZTMectdYb<4o52wf|~nN%_ct8Ai>9e-1ue8vWI-u ztYFEa!U2U85EnuMVm`pHU4Zzl1Cc`*&mas?b+fA_cv#C2HrQz^TS#;{I1YmTh2l@= zaNw?;$Z`aLH{Sq31DHzinE*dbree$M;i&$#4LlTlHi&WU0+2!lQ6AKhQ z4W?XF`(x3X-BN`12-1sM;)nnSwB`8ntp8_mxWf_Y{Mj1VWK$>6l^PRLP3uSTBB&h1uT4EK1Q0%e7@Gm%0o-Z=xMXpCmu!2&56+Yw4pOG@_fqdf1O68qA8=DI}i&j{^%AjMWJ#P2< zMs9cF3FU%KcoKX13v@TzpTqxoh|*^83$NDTtCG#APi0&st~0@`gh{U@D1)*WD#*(7{7~cY zIwii}>#h($<3VQqxwjq0GjH$QvApWII9v6Mh34P+X!@}K6gIR|g z##?1==o|oTK#Tw~G#jdt&eGoAqK|pLs8U8V* zoObJt`M=WS=8QEpakwQ-aG(%^XQPd?ZGV0Kw6;c^|UZ1!REoT3(e>0VvX+uv-_`nGzvTMt5{Pmu3Uu%|lOl)!Ax z3_*!IhV(n!CI0a(7;9d&K1JBza<;{qFNbRg#rDQ1=c?$BRL!(x5YzjrN84L}YE5-) zUOowwrdNe}N1yhd=B@!{t^~Q2!~YYFJ-Xlw2vtG=l#@VK2RI4?%~%pwb#L!opT>Za zpa38IfRd@e6q5=HhjXi39rAQ+ssMq3{oNJ>32qOyU`cT5GPE_VHeUVyv|8bF$c@yd z`8pBmcQ8f9Vs7FVBj}=MU3-jmkW9rQPx@v*Fk*B3P##4dpJ^qA%y^=EgIx$D8^dJA zAYZJIiNm{rc7Ar04MEB;2!mnv8pZ&>#F(hIRy^*J+k@nv<2>bjlG7Fa)GvVQV&xpwDaFG zk%kyR|4CS)@s*4A%2l!P-yaaUdIpb$ctM^p0;J|hi*!%3oxcD<0#uz-6G9K0#A;h) zv>durm&-hBhxH&+vxiclL3JVVtr$dg$4GK&gEOqey-725zw=%`qX|PhTq$n1*_X%6 zLb~EL0Do!63d5|C_n2O$_KoC-sQjVdnL@kgw0B~89>1M(o6iiQ6T86<8Jnr5ZmGJc zvi0(^%bJ6jp(CV&VJ zBdXQu>SRU&PYd4Q*bpz1meAl_Ii$>oF=oa?r_$Y`U-*N-b*HbJ)mCMfpN8((@(w-L z-;Owrs4|^2-&ixejf(M>O%((>KetQ;>pJu_{&U~&q=}80C1N}3FNECkT%XskA z-dMktO`&_rp19&UUa#*}3&LgD?YL0r$k09#xG6bkBR%KAF}JE7)jy#8ktyA}Mqe~L zujS4uY8K>oz&{``NB}Qjpek_$mlw96lBhRFKwx?RlAreq3ASL0&)|Zv6Q<075Dx{ z=40k@sOCXjIDA%}ufuTJ;GhU8lV`l@Y4{ajkq+18f_9!8>gaK&Wfh$L_)UNSNnmdO zCHW7Hc^p+az+6^^&mDJ+^g1rX@HOcD=s8<52B8*R09uy4@- z0u6^3v~INV1>4FUXKh!c=kD5BkdW@x!lReIhhLZEf3^^9pgoH(X$%==Xy(q8$QBB< zznF}ydt2V(2a=qU2Y8b3&hc@S!fWBZFuo9(saVEKIiE#brK#5aw*9{bWyEMg7>#%? zZr(AAaVp(HN^5q%)?h8;i_N=F06_u06W6MkmL}cBAGjJ^V=M>PeYxb3eNd;Vyk)ZMvd24ZT`Lx1Opdb#~yOsR?#CJGlh1uR;dWQ z#yT0Kk=Z?#l8Mr{5gnpRn1uS*C2Pcu z0EXa%rd?)+wb^@T*x5&=!?y9zXgh!)j@4x1w`^a(No7~HCgNWb6l{^m5nP7|9jby< zjdWGG=V=LF^jJXy2cdB7(dOsvHZllwNaW<(z9sH!o2LUy(Kcu zhKr@&28QaA@qq)R2f)CB`a;*+HYn!`B8%^*T`AZeZP$ig6!`hOi#jUQy?4*1q1ahf zH9JwJ8o%U1#XQ9SQfywIPzIK7ISc@T1ykLemjRYkoJLni#Y=U|hO@Sz?1GVua7K_f|KGQG_;$j&aF^ZJ+`=cP2{`e>&p#> z$<;0%-60`{-)Aj@ak|BXj^XfZ#rut#A(agLdU zd#i-&jXx~ce!SK9Ww$5g3<%bx;$mwFDe9vRr@a^ugNzfRa4iZW<2RD$eaA=j=4%= zjn<9uAWbSD+m0|cmuob5xWGRv=O0XH90r?0;r_!BIjXV0Y^Zq)j5=Ht7G=3EhEWp; zgpH=R9}^E5U!@F>jprn+wtLBmyslr}fa@U;r0@a)csaukxX^=y8oLpt-Ic(3K4!6u z!zHDeN2jYVE->y?@=Cxzku+i*NpdruO}l-gT|xkR7_>l1QlM@T+ZEGL#}$a6T0g#} z*-Xbw9s@d}lR@U6g@GuEqPT6p=We#ZQTO+G%h-QvO^yUUmEoj^MQKFZU|)#4Xh53? z0!^e#45iX45N=U*_X6Uy)HfB5;f05?$oVSLl7uR^W=gGaE@Ba+ABGNiFAitJ> ze-l*LDfM%}ol1KR5^y?NEnc zC$=v^j~bNutiK@Db7xLz4BLZSU4)B+U#@XB5I}Pf>jK){GTsz$9wk?^uc%qdSkm=+ zqRE5D*14WYs2jxLDq< zkv2bM0SG*E^V0q7!W`5efjqMm2JNhU)Ri)SlBYg{BN5#MPVk2Y?nZ!q9di%U8TpI7q_iq&aM42vos*u*eY)YFtN; zx`X;Fjr|~LKe=(p^ILnrW_6bV_@e$oI(z3-RgR|bIr_Q42w-3Y%xJ8+&75GB`Ai7- zX9ij{N0~-k=t+B!qTtD7b_WS+}b=TWtCeP#PX`qHpAxQF}8^NA~=(fSmoa!dX+s8|lkH|EpB z9C(tr6g5?RZK;ag6x{1RDfuD8_xBCqaE&FWI|ENoOONvx4vC9t))VQSq=QL4xb(x8(PfQpNXcAQ?uFWeA7?CqEbjWmFTaRea8W!4^7i}O-)lu0or&f%S! zAb}S;#OWY1$pTNsb1bxHXe!l69$9$e^s;5wPb*z2ujKv1m$(eO?=an!t2ME}adi9F zXo-~vu=Mw&rNUaPxF`YLVs%Kygqr!7025%*_o2P|G=I4~hS>Wud;BD7&GtL%!mYp% zAtLj0Q9E`gKDyP@O`qZj$ttf<-08HJjt!-Hvv6#6`v1Q(`p;87&L52Xp7-`+^ zgN@FDXqh$QVxeIqgSi2*zGj?&X;(r#^13xu*%<~x?9I2SjVhH+`7ricz%p6ZJAP+k z_}aqwePFw8XqQ5hwfRTs7Vg~cm;wkD7YEFqT2r$IF6*ClQR8Cqdi%fmRW*|_1of{9 zPN-Dzvy4)@LHIBCH`;b+b=vU_Z1LElGCwA@zEE^m=BwyyJdL$}s-R2gol)h$XTg5| z>TO}U19RMOfH+3Vo*QC${5cJt! zn|JOEj2~i&AY0sIbe2x0)3+vO(~!`zI;Roj%9jp74wT2-a``n>yK%X-tdi&qOfmbK zoqqA;&Tbax<2<5NN*lMgL14Um?B#%r_q$9fgByy_KweJs>sW=D0vmq`3_e8MJuHQ% z>zYUbeY`P^qk1p?pa3Z(Zrq{>7~9i!_%Y`mg_lpp9B~dgr;RamG{1`bAA5kItU`g? zd&lOuR4zkjd-#l5nL8^S00ar$dpZfM)3O`tO zAXB@k7cgn|FDCsB+iJn4Ff%52@BqbDib7Xz0741tU9a<`gomFpy$F?rWAvnE8JdDt z4A}{D^Qfa7bswap2>y_2hBpR}RcUohv@t0G_9&@iYH;ya(Wod2F2oqrekRS|^ z{%^LW>+JJn%1#lf)+HAIdi?&%&R+fzYGBN&;lAkMMZ>Rf-%hNWFOIvZpH&ikJ30^E zfneR(4F*cvwZGZHIQnk3!h{eYEba$vcrc=ix)*ghA-v!7MK5D7-GX3=nT7N)Uhz{JUA^?~c>hu!W8c2% z?@p}(H9S5bvReILqytC7oonU!MAxjfnA_o=K^n`K_pYFjRjqVB`pDB(AzU#;M*2hl zdZd1Ox279f95%8RIoqC`lxtEpJ;sMtYJLT9rFmE#AE z(SG@j!~hJ1Z%@g*b?e;*y3{|?Iz&KiSMF5Sv`d9(x3F;x=VRHl85(Dqm`^g@D#$#V z+O9Q0LKO`h5Ny43YvWEGsz?vj(!C^REzks1=3Uk>^p| z+l}%cikD{XyYEhm}Pk^@i~WOq%K0L<>^Y5_B33{!Gl;E_-K(6M0wkI}B}$SRMKj zZ7@zpWSSEH#7PG2iJhGmk1RHyC!!Xg@x_GoBREB~- zE!;+DLI|XUe}_YNvD4#aoA_+m|26;kxT(`yH;uWoV${LLZ;27HU9KQr!E_TSK}rd3 ziaN&f1}Hf`XQ%u~(K?ptSP)Z(Ffp`;lj5#biKZOW_gaJxk(1^M?89s$0f_@$i8n&+ zgUXe3;b~g1(epXmoDifD=c~F}hnq1}q3YXmAN-&hxV6Un+p%?xvn05C@UZ*JliNuy z;+&-o%5y|b#O?}4p2ZP`8F8VKqKUoz9cnQPf0KKX0Nq?MS6EKyO!w!N-J~NN5h1j7dc(p7 z^yH~%iM2|atMo=fgT;V|Et+z_hWGf!uOxIgY2UT=jh@)j-z7;F+@yV&Vvaxwix|Y~ zoDJbc+x7U%Hd=KBfIM9%ud3WEXl&?!_0TmahYg7RA*)DqVlldz9KUmjn+6qOkTMak z7k;^ZoI6aAo*Esk4-|B6^YaN*AmBuVAku#r5Q9tmG>Z&_$JXl5-?GfFdqrM7a}o2X zAIA|_lVby!ytm2)j`Gd_KU5hIGOy~Q8!&O>W^Fw*ZH?LcOO$B)e;p6;2dEH0i$v)l z`nIh*EHaLmJ3;{;Ik%vCltQRtRG00J^=erfKTf&7bl%WW4FPn4J? zk7>r;5CN$Kec+%7!gySG?P%V2Eg~>Um6~LIc?7}>)9EvM^QtPmyb7MMLJWm)f(NX( zT7<6PX{vACWw9`8^L}2^dA!T~Qy)C=d2yG?nw9Go&)P6b4k`QEgA2kCGfYx@k^~Sj zu*=<-kKx))CN~G72p}A}ZDRKBcE`|3?0~*WHbZPud(;tZWHPnWx^3vb^Q2Rvk+uHq z8D{$A)U-31q#iL2nV(%%O7S06yO9959~|I9;%Eh zOg)8J=M=WHf{Tjg@@LXXDCLOEq5&K9p3k$92w!^d_Af;0;?P6}pGl}J@0B^yK9(!!sZK@xCQ;J+%CSv;RAY^Z$3*=p*!hu-T3{EeG)S+$r(&s5gcB<<0)B zMMuoklo;?LqcEZXAj30b%z=O)i_m~K3t=2jz!e~~E5!t)+o zjG~b2&$;BC8Bf5XrKmygQr>jag@|rh3PLLd2B{z-vHou_0@nSY`RkfNu2c@eDd%k*Nvu9x2_7q+-9Xmvd*vxa+_=O+lc{_Cigg(XAU_;qWuF)9 z*I%sKtuCdTW^Lg5hQs%9BZmJrFmv8(;qf(a+Pv?f*L7W8yH4Oz=r(KDJeL%IW@Q6x z#yoISsWGuHhfY9SS*m<%u2X9!Msm{dDwPow-TO95h@kgz`)+s4>fYot-BXf&Bst}OIrA^(}moVq$jf<)eZ_}7UPO8%dd78*`f zswo>1=SY7RuyvY6FGXu94;c2)80GAo$Q42UZ{aMeR#y=+BEq`1PdHlFuG=dj+V5Q4 z)mEMj4a#(Snu6r0Kl4R5;*Df@wzJ4&RK7p+Usl3bGGSLe1k`mzu;41% zgLZ;tuoXfF2JteBr;6R41{VndS}cdO7f-%?yp(j4E#rN)>w1|W!0znW)x^N+^uz$a zjBKnh=qE@On*dX1tWHCU;x%;n_~^FUOJ4&+q}8}(3%C=pOxJA9y=JeXd9%5chji7X z%Ej2($4^Q0Nn2NzwWexUGqa|X|6;-QvE#-x)%s2nNSeg6ooLCDEV0s44AJxmETkW4 z&sY-L0&~z53cS9NB-?xz6sNZcOiR%9?%<~85Mw)J{Hf+<%LU5&+YIbMkko3`U6FaA zyNfol;_$7}Q)prY`}z1;ePm|nES2-Lf2MB_G96lhhrx-?%`FYCnneR3n)lOJ6Gzgk zgdVsWnkrHgBP&~bZ52MfwipQMStg3iUah^sw2_s7S{2^(MYS11+lK4{m85NH_DPo3 z)Ger*1Yh@OgszHaz+|XWEGis0Tvd`PtWD}G@w%5Yf{Uj^EC#aIu8~GPSdxn#(}(*0 zr1u(@)n+DyMj8nZ=*>SpL{-J-7}UaVtsNzG8zrFxmaKb zFxw9EOPlZRsCDPNd8dn^&hdMlI!bv1Rgi;U_j$c!d;}~QPi`h+KwGD#isp41Nrb(| zVpU_nZ1#TZH8psT-Y&B_+f<%&llFJD2E%CxNxMN?%(Fy9AJqV2bZ8~_7FvD8r$MLw zh0i7aCs)Dc_4X@QS+a8;^QDymsPOn?rAktC&vcC8aDTbR7z3KqVe0qgwY5!+*{olU z+Ek{x3wu_$>gjUjpF4TtR}y_l06_#=SI&Gl3RNs}A8Xe3&KyCS#}hx{KouWv!`~79 zhG)g(=&uu04g5XT;mcxM-V1C(RNzRBurM|&&rC0bTarfo;;NXqqDqq@NbH**DJMQ} z4egwgry^qP>h+^L=ladJT;ynP3gH`6*y>~&!praqRRLDGEtL0Q zcACsbl&|o#zu1fC1_cd*4&{*-ok$IWJC-K-!$ck5TfwZ96m;8$??n2^y1!`6z}vWG zyh0PQME9`13byk2x@u^Lc$t9Z0#}MgPEzl!=Gw-xl*}J~`r9y`Pv+55?y4y|Sw$ZH zf)E6Y;yW@m{p(!U>6D?k`5p;hfjVL)m>pTA)a5=5RN?A$#eBqc)i+Pw?99-(-RfS!s5m~kkJB(zh zB)t-DcrlV#*E?Kr-kcMitbB3q*e|qlPDOD)o5AGIs}Qh0zUba~K8~Mig0L_I1)+cd zZfG8wDU-q235#UoM&N=4kU;{nk;(zCegQ4rIQWy|Io+LosZo!@Tfe*X$Ezek1J+0k zXB3y!7&3UHV=vYOV1OV~XOjnxBg8Vnd|4XCyDDylCEZ8@1mi7)z40{m@cnIxllv#; zq;ywvYIvN*Zms(FRgJ#)!;j;fdoxJjhSYTqiJxsU7#GX`vI3U5kl2z4Aa9a`^Q3AE zSJ1R!s?QGAFg?teF+m!gPzU(fmDa-C8iuukkgx5|VdRf-r8f(B_@{>Z)2 z(pb>fA^UVN>{pH%E0@xE(U@n4IgS3{{WmXx1PC{e7Nay$#`RY*K}#Wc z42tH$a-N0bd;_L?Fp{9gdv1QLl37)GjLNi5htzduds5z2rx&W?v%f z!9u~S)$WKIigXQ(^!v_AOA6Jo%`a^J&-r|iy6Ymixj>N^0tDJ4q-i8ZN zHLBywy_y?6PD_vMfrqSyj5w$eL48Go8W2LiZ=oLlS1`CtL%UFq-;<`$j!D*unpxJ0 z$($ibMH~50f&`i>?kLx+frxuuT482@gwHrMzkIACl zOAZPaiF>}Y6%4x%OR%3NnmvQt9^z8Ks#^nt|_!cNJgqn%B;gS$Xu@L)2Ym7&#pB;f9XjDfu#=Xw3ZfOr9 zW3Y10^~pn&SgaXp>LJaXyUAq6DzHTeOXMUr_rmXIq0r6pg5I_)JF9jS|_ZFIp zol?cD>mA%{k0p^Uo=>03HwK(MtzaXnv!*N$^N1Q+G0_QWWpY>EJ^(;jl^$IC-c9^u zuyF4A0;k!c*fFNS5C+tID#2lrGwT2(?Z1N4`oG`9#A+sQ{%iD;ivyYdn3%KB^1k`_ zPr!NiJ^p@!W_#!4FfQ7AMx96Y8fW)R)foGpnfO{lSuYFz-;aTLrbX=mMHpncGra*^ zgiq2KkH`32Lrptm^bc9*__u5v%Usj%^(e^y{2{w=bOZH1O1&$yG7!&{=zb6OqBG7B zoDxENGugw+Wi95Bb`)y=i`BF%m@u8zoaoH%gY((N0#L)PD7FV>LSbp7 zUJr#e6!9H(n2I!x-gJeIZERd0_IgFeHZ~5Q4A0yXIbEhEmTyUmE6StRoks@elu-I8U++87!BG1_np6#DMpReFnxlyI z&dZA~fgqB|1Oe+^CgSO|y55_qs@pH#Z2p2ozi8@*X8$l+OB+#`3}`JvaD65em(814 ztzilLO(ptbeOrr5D)8q{L%_ruI{0a<$6iVg$n&7&VyKJspd+UuW@2i$i1>UedhczH zBC$SMf&?6c))e^Yy+_s^E^cV}K__4n3!rqj z76!QxoOwJ|uMF7E76qLZR5KrEUkK-7Z^loNP0$6=zY;3$#i9)N^35jyW6N5(7O>Z1 zLoY}HR3EG0g4z!U?&)>>_+>J&1_2KqLDf`y?W9u{LBJq2)pyjG9jA$x8xsAF|EW#N zh!)1jb4|dLF&(WYOFVB!yk2lJmRNp-+hoDZU&#rT#zFfBQ~`6O!+f% z3V_HD>#ehQF^k=o>?q%HYV40;Fhb=Z|J!>0KBYSxRIxQ1Je@A_SO45JdSN*$?7PxM zr5^{r4AA6F>~r3#p$K|QCep4!pGkEre#zaAjibk`{<{@uyid=eQx3p3*29)4$&6#z zs;n1t@(fX;uxnW2hXbfyttE}_uy*GWB3xXi6pjW>tElGuwGJEzYq(L|FB*IE>&iJX z6A+3>$;VByw$A)CAX936ium@ay{^u#Xqf^HIrNw+1laj~ujA^?G?caoB_>yN%kuh6 z#had8X&N>wRuoe3{k#rJ>(uEMqEfR~ez$fG{q-5-|K<%^8SI&`A^zjaedK)zq>9j zhE0#ye35n5veD3x8C06U{AcrIExH-Q`RvIyZMeO1PirC?^Km_%-8O5JGmL9y;a-b2}auT*V1V~Obz-FuL1=A-~1%JY&A>zzzzx5GP^Bvg6a$H^>b$lMuJU3W=a#*dq7rD?B%tNeH4AK)=BGpNwGH8@W>D#h4w zb83{V#0K392n7iV6@;COE|~JEra`n;uqCpe|ctX&@0zyLHsQFT4q}hXTef<5! zaxmbLYR^VR?Q(POG*bQy_J8SCa+fE><*SCxIrS??whBhbyEQ%hYpIhVh{5O(#m7n5 zV3cXLbhvZ_1RwW_u4mUF@A)}Bg`Tg+z5Z1%`8)1M==Qk0rUp}V1P4cn0w#DcH2HY| z69+<%5b?Q9mVvbl1JrllqMX`EyuUrXVP-*|@|c**Ho0^;MBU^srwvncy?-PGDkv8@ zTnZKx@+5EP_nAYd(@{J0$zQ$ov%_UASuE2GYtzaJI`2s^40CytxiMXqfBJR=`jX7T zRK`o_qvHySo&bPF<5Nz=dH)95*qSYW-!z_rq2OQycOW^h#OX8B!?)+iFL)Zns+nA} zk}0bG++;PKSh0VLt|}nX$Fib3iC6eX2LLF#lBoofjf$P@;S&VI@(y;qd8wtUpIVN4 z{wxez3mKj-Sk&sY1%TPAMg9r9gVo;ZbE9_@XOw7T#J3*}!5#IHkIp4E-MKVZN8zjN zxpSsHL;(Pz1W!@tO1OtnYR{aez2hD!+DerR#iZx6kZY~qQoD@G(?Fr|c=g$`mqb=p zCKhpezsf%seEJi6ha8JsR;CtO!wF8Zz`NYXya_x4}P%8pxoYdKaP@8++gLqu@OGL zs{zE(d}{QzRY&{($T^>3rhR%#n``)>a-?>@PtNNkj-^Xhd0uaSTbxavwR=bw{ot{`!Fs%;X)rmp5r;0f$)$8Yy!Lkv4w)fxs zS$`Nfn#{2P80CIk`2rqJkQ3twqWm%tvY_Iy7HmmCEM6`fDMw>aG;;VRbh`7u6NCf4 zAQ~AEX2}Vm7dc1;9rKzyYso>0-VMY!cbeu=W>!TK7I|Dah1@@w2wIE{jeS!#{_dYC zeqLvNajC6#*}BiEY{tgrxb4L@BhEtAmX0ayhaaHT@XYOK%^rgJqSBvD0bFtdZ()@v z#mk-P2W_e$r{fr5OceBx&Z9l%-7%VeES} zFuR2`05EjIK4p=#hn;#$eX8cg3lADfsC{(3l4_a%tbFBJUTHVQhk+i+f_2`MDv9W) z$?x93E3#EqoKEnXOUC$dF2&tmwfg@|#{++V&$lm_rqftKDzUzwCt_!0Tna8q7bGze zhmdq{Ic3hXbHw^{iA0CSSG$saFU}v9lcpw%l#I&Je3cUu4+l1#L8$5k6D728r|2aP0HCBl0qR8?NIRuna)<&D!)8wJ5V*j)7a^xN_NuIdmc{sl_ zNBO>Ps(l{%0YTSD%uBF}FP&O8Cr16*sH5qxr)04+xEQhb+pd6J^qaV3Ig-&oRIC7L zzra@f)b4EApnkV%KOS2hjE#!6vpGRfCkKWDf|U zvD$rT?O$v3SmMAj9oOzGkKfX(<569C%2gLi z_}?j1*qrU2H`W-+`dB^!87%7RQkPpAHXE z_GGj4+>_wS;!y%btmSxU++Uks;a}*t9xN0 zc(m?D)BUMSn*31B`8}5L(>rI?hzYl3E$+@TC)`15_2mIo&en`K;@c=FRK=sb6yp$)PAr z03iZica@!hhv&8cq<}AR>^=vWQzV4;bpf3LW1oGNIkI8Oes9q7QC8Ydt0brXeqNYy zzRCoQNQ5Aq5FrN&J-cjQwO7kUv{+5-?V#FYmxhaHu8q9=rMEU9V@rkGfw`wDzJEp@bH~v>;i=CTEihkb|!tGq5*6#^A&r0c^+uAoTs06{cD$LvOBg((O1}Ow>lxo)IHMg`m4M znyunu z&r5GfTH9#RW^?Iiq}0cG5$L-e-2o6DY9n_hZwQJASfc3XM|-ibEKj6CFwO09+eqx4 zrt?|g)ZgH0tV8*$_*g87cGOt8xw<=eN9F+mUV|Ia9M3~f^6WORbXI@%9zeGx0D3bL zlSMqpFa1+MXXrLiDv}%F6IO9Rm_RnnU_fEw!}RuWJS$)q*240M&KTHW8R;kgtBCy^ zy&7RW@)~@zo$Pm5wuW^1#$pnU$0QITeCP81spJ)iNP1GarH#k?Yjv~wO_p~*D_CjC z>g=V}QjFN6#ay-+1yqdtxxrsSm%_k-`};CrRHAB zK}XhuSmlp{F?C+pjo(P*009tCLd>^ExsSJ82iKA2>UXs`lLRp#Orj-b|$Pl^w2;ZK*Q5F4u5A{0TJ`|$=3 z0D%MrUB07l$S}N4A&vL6j@C2AY(fvI7~hy*dPaZ1kKjYycvDp8CH-GsT8bH1p`RKw z^#DTHzy$@GV)Ur}@7d|E9hlV&&Ge!m&rw*n4#NQ&S)_wB+=4pVx}xC8ko`E7JSdilN|FOdPfFRls}unSo~?RPLlht zeaK7hHl|;Mb+oIOUn$Es+})hajxguz8f4kPHwZC8OV#s?EXKkHx4}zM`*=vk>UG^a z_-B3h)QBRy8<92FLDn%wH3?xR@*`WlclLl{GGS+d;Mlqmo8XUK%G~Vswwl=<7k|Ha zYIVn-M8`(17I#L93$2dCOh4OfT0geW^jBX$mTg_({x35PsC~U?57wyFNURh;RAFRA zE)=)qj~L}JBs3htC*2ba0NF6euW$ZT$^@Wn6bl&E!vHZXOpIhuh+rxPLL_7%5JIUW z1+0QGnki0UTY9xqw_ab1{x5qqm)Y*a`FtH}sx|rrI9Zva-if{o{0h`XcJZPM9dAg) zEIzafd#tki5P}E>01Oad7zGqygBAr!Q87!YbO?xxsSy;*u~~TXIyIu{)ny@>Lu_r3 z_N%3GgJG0w%!bc$Cr=Azl1o9%{+b-$=1wND$0gvcwjGkI59& z7!8jD0CL`#UubXJ!!lvJamDukon~-T4kM3tgxcNeXTX~kjvur%ovbz&eisRRWg8*d zc55Ofz}fKn3ZSbXVhJp2h*MP~Ei7y2U&ES&xkc1IFac?@++#exn6-onA^b$VAu4Qy zKM+9X{KNtX4Z~RvN9dv(?H!Y!;oS?+_Ioq>c1U01E4D&WIXuqR+Sc&f(ncnErmD~G zzNgpQA=_R8k=Y{~!4VRTKcY_QjXgGT)o-c$^O0Z6LzPDX)Dk+HF`yJQ(&xkh`cH&g z%l-Uy9cf?fCFU_7yFtdA(D3%m8rmpbi!1qlldeu0bPo64jk_k5i{owNTg$nHxD_@6 zm9mnOT#MfldOKcQ_L`zwO!q=FFo$pfchXr?qS-B-a{=ek zBm-Y`%#F4gm4RRMG!t5JJyL%YO>g{TNypqC+!!@pyuJgBi9ZSW+{kZdv=x`I$ zJG(F!JHrHn;zl%RL~qI_RS==pxYz2Eg$U7(=}uCSzZl~P<$R?kN4D#Wa2R#cC!ojx zI@EvUTd79aG7z*>0}e8A{+D^fLENqH1-HEY-S>0B1N=zo_L=*y=Dc1-pLu)kSQ0R7 z*F_ehcU$+-D}e4M3#62J|ilj=%0L?lRe9wjL$**Mjey!rEy)FglV!`)> zb?Y^v+B$2`{iY}h*uVf;hG^#aHe6?w9X-JBzLRgI*l`2kbUUxjl#d*=?z(4?(3_ERPVK7=30OjwgT6&}=GdKfLNB zp`<6RU_O-Y?ioVXCfA9(iGnlp3~p9tbQg$(UqKgLlR&d{q$zEIC)8&?N= zS|UV0Z~ql&K|S=j_R&tTWX-m>i<9g!^=)f27OHjNHAqPrhnUPiVpSB)*t_N7ip8hD zK!SDiPk4~Wp0Fg^unHV!XMF3Db+9+V9EDeM(k@%w9S;yH!|shjE&xWqhl9~&c~Q+} z2p~`rAgk!?FmKy-pX%RlWs!Z>OMV_M)=AnI*hanC(o`8MrRnxB9DkAI;SBk^ zf3luqvPD+uh}LK{@-P!$H1+S9U7SbsRHauu{1#jKMh%=%X{Y)4a62G?YI@|yV#jhE zOxadF@5t-M{-09aYqf=^Cj?A}b92oI56xa?7vv%>*){%p&sIv0-%=~z+Ic=q-_E+u zK(bOvFMi@R>9gss;3(2nt2RBDf;_QLt$(nCmMmWOD?j!5qeBCA8e)0f)%{G4E0}P5 zH;l%l3@Pq$TnVfP^r1;DP)Bf9BOjadyk&n*$9>ryp;)F+Qagv8)~JA=quM$3e(!7O z^F0_Jqw`iZkUmfC(d1eyo#Oa?=MNP!@%6c#62G9{U(Y}GWb7^#>0ussi|hLvXc|E{U4&VMVpE3x)H*D1^uI=W~sY{e3o)65X_1$DR{% z$SIsQrqqR#`i$JHbwPbJR~E6Iu2&cJp4**aWBrI!m+ZM5`fsg-D|WJk3B+iZ()A0a zkx=w13Y_q+b#hqM&7E`}`UGdH0a7E5=iOnQV=FglnZ}Ol*&C?Kn;*!IHg03L;)tx^ zkI#wqFe2%^Gg4qx^L)Ilj#57}Zsg@Gh|Dfnkgp@}3iX_tQY(t~8gu|;U@Z;z|&ktZf z`CUw&Si;}GR3fMhi9P;FEF$&%dUCIpP9#7OK-RNFZFN~S)AQtjAdBd3;_0JtWQtCf z{M}Vt7<(g@KKFjG;@H)8SD!U)(rV4!UbWOYq(%6xDeExsa_oI@vF-TVjQNgQSqO)G z&S8|^dH5)gYx;}pEXE|n2Lv#~5`UION+MU;BR@w0&5PqXV{)%_eTLnjNgvK6fK+>` z?%9$}Rw@-R!Dtk&`yfFZ_nc=m!;|JJP6Gpc2PsBWuu=>PQXIcrh)O{zFeN1t3PKyp z5Wu4n1YroI83{=yAPlcKFiVI~Q8|uN4WR)<3MdeSt}?V!9#_z%oGSLY_lA?Z1V-+W7nJHyVH8YFVBpVWChM7XiRMAZUl6L5JGHckUjJ zrts$eMEMcOm~Ztb!=cQ|xpSQ>ZX)3N`kf#74t{d+zHduiAY@0R)yO{R7uT0^ z>ARWaJ`_u&DE9N~YqDA9Nbx&CO)a7^-5_^UKOajMH5Jcox;34T-(^3UQJYu&uZQMg zxKfjO;#yV{Mx*@fsc~KsNsDwOqWbB3Oq#Dpq9fQr17I+M0Ss~DEU57Y^Bp9B!S?hP znfD%@s?PqNZ`Tfy-)d1g4KK35C_ooVoz~7`VM=N{L(;ls7{mvN%~-C){`b|N@6uG4+0(OKi#s9Vw!b&CT#+!vSzJ@~WO7F5Hp!iw)Ysh|Y#f=4}q$W>x zpN|E^+p_B!EQdmgtJMC-*`EXuK2TaHgh0XYsKE0jNSV95Mm2hNk(GPdNi13VcYTT! zYr5`i7d*cYh^O6(k|w$U1c{8Xfw{ua6R%eyPMxwdEM6_Ayvr}6<*11538a9K`*414 z&1Ga(Mhnw*iBqfB)_YM(!hsLZ%MRhRYrTQ|JG6Qrx#18QRey+B`a)xZ2oD%rKU&@` zZLe|ki_v*<+i*3bq4Ahqbj{bE*7#EnG;VBK&{cV3iyywfurtQ4E$F0jg@QGO!~Gaf zv3ym*;5dlH)hJ8RcDfi1=)eddFngJ?L$klBlX(9glTN8i2(5@I#N&=$4@}|ZU7AMN zRI9H|R=Kt=+rBom>(JsPVZVU>nie1KKU3BvHA7@6`y0}Kh2J`JtY*Jekaerz(b}t;!C+OM*9gX#{#_^lDWCuRW^Ron_@!-`}*y z@Z7R;U!}1`0rvEc&VFLPGY&K!`n*>aTvwPn|5>a#yYo$1*vO|oa%n-%4$LU~zujEd zPyi`@%~(A{gRwWv%6{S*Hft|P=65_G3GbOA*p=W#d$K!xg4q6!{(fzF0^%j3A@(kL zC88#S&^_8DpQ%Ho8&&;dVDIlLQ8P2@B?y;&I@ahVoDB0$jMPAd7w|_8!Mn4G87cgz zL-bF3ebe)k<<~mftAfq)Ek)pT86I%CnzXH#UnU7vou2xNSgYX_Kh#+3qy~=Qpn(sA z)Y3_IjovY4tnun+nH*I8eL|FuPMuudtVrkA}Tmx4s-kaqxR~wHV zLM)xvjGxHd*IYBJ{RIvM!L<98{=H#X-S=ebNCv#_ey?gd2AW4oDsE~{OXTRwUJZ!hWN=J@cvqa81DN37lu;=@>K27YH$M*nDvT9;- z2*~u$_Qu{VJ2$LQ&5)Gi^r+iMFQCd7;R%Di>uriwYGGa7-#B`C9HhtjZ+$I*+O_5B zd$V(l(Qczprr+TZ983TRLMAD`dsIm3MnJ=$eqR^+HVo)mfmApq?4Slo9yb6*$Im+(q|)I7~48p+eh_m!XKAlg diff --git a/python/tests/reference/Result/place_2.pbz2 b/python/tests/reference/Result/place_2.pbz2 deleted file mode 100644 index 399aaaa7960d0a61c664cf1649078f8420abdb77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10851 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 diff --git a/python/tests/reference/Result/place_3.pbz2 b/python/tests/reference/Result/place_3.pbz2 deleted file mode 100644 index a5fcd416861391c84cabd1e6c5841acb3c7897cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17373 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 Bkput$ diff --git a/python/tests/reference/Result/read/test_read[0].pbz2 b/python/tests/reference/Result/read/test_read[0].pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..e4ef0bde9d2c2420a0420171b8dad9ae1f2232a0 GIT binary patch literal 286602 zcmafa(|a9mu=S2@JB_Wzw#~-2ZQFK(#>nEwRysa`eBD6T{)QL5_5!_?f>1u)2f9F~ z9Up7Q3#(qY>-sC7%d0VO&y7Z>o-KLXy3H`K3uxA`zN%NFL9afGrA;(0tHG&5z*OJf zo1(sc(Tl6ot!G2|${`Qv>X^>~+TN=4)>n3%JK#+L za4&(zfRkDsVBahMip#CKULA9O&CIg4OHikOkGj8BJqV;bPR!#J=>@Xu<+AS%18$## z1hORRw+u75RxFNMZPi&ES9f-dZtKgzJ)U;4{_L81M=R~A9i2{B6t$X!rwYFIh1AqtlVORT;D; zz>;?bEGRF?bj;5sS@H4$*>|@yT@V*+l_*-Ruy7wv?L2{d*_9lVe%2VytU4~D^q{z^ zdjTihBU$D^S8K}hJ!@Ojt54u|a3|p?*rwW0JIe#asN>?P;lRJ8)At7SzuYxCEN!d^ z1Z#8(p8(0ISQJImA`rvM5E$gzbH$K$g@D^WkIW`zX(a{VBqjpE_sj&Y#m(#}V6V53BaHj#> z_8@t@*z7Rmaj;m?HK+%+OXnT@yzu6pZqYmCv(4c1_BPX$sJ4|*UtI9;nnvx4>n=CC z7pmpy`nRC--CD1!9oPfk(lJ}t>~?tMS);bqn>k~*QlbScDCy^60-M#g>e%kEgQlo#rkv!+CUEz(l zW0}&%PlBw5)(%6?t_!}%n(VdO&QPb}`VF9ybX~*i<24Uz4@jWH-V2m&-)-*%%IOUzbY=dp(E+Iibo zF4Y_HIV1uNy`5g5Ig}3OjaI8MuPMgH-Z`*)C-=b9)n#`gkGJZnV|~FE%T>dcCs(b2 z-_EUmJ5kROH*qhCqdqRE=V}vJwYuD^?=-s+x4I5=oxAQ`)0}kl=PIxSYIxy(x6D?y z{>FXPn>Ba-m&86F^NO2Fc}s!FL1|l{gKy2#!Py%ToQNlF)v@K?aNwBRtH}v60F66s zl5DwVyUTYh*>`8HTC^AT9OpP*cmln=rdt7Ly?&2cN6gNu`8AaS-&=D{t$_8tgod78 zDOOu-4Zuz!+t!*3t1Z0>rm?a!V5?W|YB8Gl8%mG6*J-t!`!Fj%(QC_*yM1 zW&?Li!^&>u+L>Cg|JrD+w!6S|?x5GY!)VL#$lWk=vpmmSvC^)1stp-I?|d_m_%7eJ zcDvQuoI0Q3L?5fqztMl*SSV{(uc7~H*6TIUSf`jvOb)G74!~8T3PGNNSWLfIj0kvG zfQ*9-p#uO?0Fajez=FCc9U=gL=D#}ce=VfP=;#g9r_}jXaJ{< zbAxIwychfZ%L@Jdz%(`<4SCoQ*Y3$y=k3d0z3%#Y$0rTGKI?(Kl^wvWtJ+*f%U(|^ zs2*MStDTyii%v%pP7=#Xt2IXL*;XHrictHSqgU1TLHEjqQ0-QGrEQC0?;5Kw(cEda z=XN6zp2E&G%4KhFZprqjt>@lOj5nO6`?hrjm`BK8+5N{ntG^FfK=lCTbPRL-&)@AaVXR)oaxLFayJmh^D_$U z%=T{8JBbSfuUr=lbQ*bU^^1Y$`Ue_wcixUV1JJx%{@&4r{*J>NXZ@YJtvsQi zt5pBKZol^2OruWk`Rsvyvzy0j>Z?vv;L}DQNl7K|Nk47>18eUtpY@-fYp>4m@g943 zo_?=uWbb-sziYTYu)l;8RKcau4fC~w!WgJ+=YBgo-wCaTjt(FM-lg#^V71>Mt)j+Z zsMaj$>+TrqXE|%AZ>dUaXQ}V%vF+%oL)@x0oH&a2y6E-jw9nO-=1%W92G6}V+9P3| zjcBc2UOHW_*y~u@<@aU^a2afNJJkyCr$&6C!2ew^D_KbRKMog?I_U|8YSNv(bd6001=qr8$WJLYx0WcspN6izz<>{BZg_ z4jaV;MMVIix^E4JA~^th0RYYUUn>n3`ef{{;{WAP%q3ta1enoOrUPimIScb3{qmI* zv2Rr5+7{YLI4VER34$te@q;J#bOkI&3|J73xEYk zbI}FBH)zVz2xv*M;c~+=!r}iJLADSQf*%5qf|isNg`t3e4oRbt{r6v;77GF%`dggZ zw-|K*dc-%TdRgK_ObA({YDDr>d5KI4bWush)E5bOx!ZFKVOeLRIC2UKJk49*O=5Qs zA@S`rF^qN$o0QDmb#~F!_cmsUblVbH7Rk^b%@W)>{ec)SzVRc-u;3TN=Zj*Z-8%$! z3gIqA9`9_yN?v|->9np#-Q>v>V^3uM1S&`>!G4| z9osh8oE(cMT1^*LPDuUiiDO8=a@KKX=qYsFY?BAgo<1I%t0%OL{lIIF4T(XR8X4vX zjZ$NspG#`Pk}~6#TE7DtkFL55nmQ2=^baVO<+{ux(Aj^(L#No!TA)Qp1LYJz9zmR# zl!gCh8c;6eDO5uMF+f9oCktdb;s!>S``KFAtdI^Uvk37U3K#)4EO}AIkNq6Qqf{YQ zpz`!@nXT;JzA2FIywEo#U8mXqlwF5-bw{ocf9So)r<7frgZVcUQI`iz5>dB!qadpXQ0KA8BXr$ z462E@C$A=%tpzs)^|SMNXkVmwa**v!05LtS6Jp=#K;fy#gvVsvM&oxh^db@fn=pn| z(nQ;IDJF-_EZeM+FX&6ZGKdY)RONOm&?EpU)l7*vD8sg%*mD2dXr40O&83MtP&U}) zQQ8Bv#PfKaKqV%}_}6TV{Ob3%WY_)@C7;vo@wq9tjHTSK|bKKg`C`v%wNUHC*&_TZFI0ubgpJYY`$>XwGD4m( zlWi}zTTgxEC$@LYNf8M5(#JCan0Yl4LYQu=-c3abEke8YZ{mk9S}U7rk-R?!%KaWK zA38bktIKoV5Vat63hI5sMp3xEnHFsiIWon{Ra z1UwP%EEA6v4_8=ua&1(Y1Z%FIa@Ajr6q0nrda4~l?0E>(UOYPk9Y<)dW7|iuT zpy4odU`P|XU(1R_Mjn){ytsbap_*u{;d8pNm^f4?A-??JqXJg|fIv}yUcDjv^2*W0 zKp%CB_N;iI9@qc=Z~z!XhZglDI2U%jp2f25g^!|=kJ2a~w?gtQV^7 zul}}l>*p>{e&-=R-jh5%O3zfUw<*QBK$&?EAiL_UGYuCNZJO^z=NC$euZ|;KB7*`w zAlIB#pH#2duck& zKuy$F4S8zLVIXHSQFO0r1ds1RXMU@EH;SiyO}aXqJOi+qNRP6cvgi%3NjtnSR|Xko z)kXtq-9&Tu3=;)51AYpre`pL&4>QAgoHER0g$$kTc6(kw_H0SPs$~gh)f_-xHSdmn zucvv37DwakFV$V>2gK0UBoC_ylCS;TFi3(~ijvT9QrPoWfP%ruHRwSfgId$2oe@FV zBbFOMX_OIf02tu$*cR~sR|iwp!zWg8)$Eu0TkXDImHSbQGY;MHl1%2y|2d-D*3U-A zD1+& zbR2HL(n)!zBh9m@YlsQdn8M$yo_>o$=S9hLe%Wt4bL_q7$keg_GcxzV@oVYqIH+Jl zb+kVIk1ZqtI%(W}d?p{c;NLFX?tkiubaZSceujNZM~4RgMuftS52}uD$9s`mlO*!c zS?N}%vz&1r&1PQ6;%Sw9K6F+Qx)mu|Tnr-`vMtFJ!cz_X<;HpPBC?LwoekdnKa;+z zjAe_K3@a{7T2%xX>=`dqeQIW3R0pYx&f$(@Fd+6TXc^Ce$UDX!m+MVWtc+jJ1FE!- z^V+z|9$`T*uDi8mKhWmz9>wgEkC1-!S|`7RhT+y>NtTB;s17pev@o%2j8+#(Jl-ba zOdMz=b;G>X_iCNBxB%@Z+&pji*AVcY^>^#;pp3n9`(g~B{s2ssoSP8IeIVXF=5qO zz6wg2=6T?UUv+j%8BQ+QS5*8FeMXD6o}_n5Nug!JZx^f~d4ktWEa49*S=rc}((inx zD{knsqY#n#A#+^dMuqm(mzBzN4N2%yA<|zVWdk%G>H*i#v|U)u&TOGzb$O_m5Z(=> zuQ$?%Whh*15yEEk`Cg48RC)$Zz44~$|4zHO(1S-TkUuG~eOdOJi~1h7_6OS!;Yjvm zzJ`_rmB>}SQD_uPpLgJe)T14Os5U{iR(|$73U;289K_fA-vSp$LUO)8TyY9H6-A^+ z$M?xRelf~iOB}@`vriPhF%PRg@J%`DLvy}TLy5`0m~qq4{;n)(`$IY5X?L|}a=eP> z*}xx%!Q6)708Ibq8k6F``GEEqB1A;657=Saq5p3fqDDq(xPw`s+vUq0+n085&qdj zX`#zpO6&!c-Q-8heVHwb>oo3PLSH6)2~;^G8x^7KmA!#A<8(&f2oCwKH~mJC$jpep+~+Tet671j@6$@6C{W;kFS_qLLL0mpiP)1O9<^R#T9l#FUWX&{4sQaM!8h7{o4e)bZ1|H&mqYz zmPC**!q~f5hzQ5ckh~HSF_nWi!F25MS}=+l!R2mYrqh$6YR>*4oe#64{N* z=_xG``RqhW*=#=A@5b*Tj>R~=L}o(HSm*> z;LEhV<*255qB^u7gp}n=l~3cV_a9%wZ}b)d?ZN6GIdz`0AO`XpT!o!lVco8+ z4TZrG{dTGOH7{VZE}GiUI4d(T$)h=wUdrX(b`rp{zUo%N0Y!a1st=Dp6P63+wF3e| z-)66eB+T3l4^S*?wF24c$P^5SHZqpRPtwO9Vi1+Jbnu-FsINFfzL~Jy=3pZ&}AB zM@?1&r;$+j+!|2i2&$OqH8B?`Y$gDc;hvr+Jx({xL7O*H)76#KCX6>et=AcPWTL+; zLc3shbmc$}yAmrn7Xysl)-vJcRO^T0@jwOHHe4FKXV-`eYo6))GbaCp@d%x@E+wq> z0*4lu2qaa4Xm}{4Avc~p$Rd<`|3{)FBm39cO5UW~&nL8DQPmE#3Pphk1qRPexG5TLG(B9BS zd{+FuUzb;9C5c_Jy-p)3nDHga4Occ_vp1TW3tpRhi(>_wThYel@QdglB}nM55c`dC z7jZ}d(m(F&KPxg^%9a#-Kd}m-4IYGz>0-PlD3F>BKZ4yxYHTewAncAc$n=Ig&XA%^ zaGig|?cKk()E|q2L&e%o)|qW#G!$KhAz8e_LQ{Rjgh%Al(P{{s>lQFw} z$EJ~v7%jmLvLc{5q}_#N|L}u4&%&M=8f_C~4aqDaly4rXNNa3ndFpvM`YCYezC}tuv4NnuUZ-IRk5!d7&-TGr{rku1d9EH2$+A#eLDjiI{PtrN4KFZkQ24&eG#M#g? z2+W_(#&XnpdTbl6Tu2`OJQnLtsduIuzy1zJ6+QWuH_6e^P|^G@zv7>ja@u$DJ{^%0 z6YVxnvnfrG?{%=5`av2-_t!&ZZC9r;EO#nikvd?pLf|G~!o@>aPNzt~*h;w^FXdWn zhl_pr+kT1j0`9*Shc;#%mOergfGQ2b#o@8D>N?ynOjwjRmr4dJRj-5BS*v{b7c1lvv=Rq;jKO2G$`5 zmxnG?@vXKCLZGyg7UoVz&>Y#fT{>AzmT-pCq{~PtA9N<*i3m~&t15mYVm1Az@Td|z zqwFkOZ~^nHItoxKg)%P?UnqKnb)3+z^fQ}APgz=J5;TKtv|L#Dr9!mEu}0Zam@ys! zqeR?+vC~2LjP`_RtUc+%W@4;mZV;br|J=53Mo~uq?_W>}t~X$2#aUz3adVU4Io$FO zsA{@REGP96-Xa^mdqjZzyQJYu9)>6(nSg_Vrbp@A&MVMqT1oJ)2t0*R-pGTRnT*+s zzEj3TnI`1-+?E)6r5cu_KV!CCGfs0s0ky(@{tpp%QLA*c{KtM0rwnbE?R|%kT07kV za4@pn$cXRIQsZ;E8T?J{=&RD#$A6~T^u{jg;IYo-Vx6@;jGXc=cEltlz~R6)N9RR3 z|CEfYfMIRF(#R8DuA~E>VYcMdkXx7pR@_<{Kp`0D*ZrBfB;B@#7QLzzi2OL0@d0C- ze1=Yr>=F3s^_KD?)tX#(#iqNVtuw?~5&LreFe>OiM_H1t0RzMR;;AHm2#E!sLVAkB@8B^|i!T zF^53jy=KDj%@ea?9#kmEhM2|Swjx`_;so;OJ+VKj%e*AFI=f?En1%1rGf1v9Za%|5 zH@B@3?`%;GPTT>SC0QH;2yPHfJ|r^_&bF;%StQqn))kIIxiM~T?$Rq8<>s8|DkI@g zzRmX$c;}AwgQ7JUe&#A&b$7L+1l|QK!?S*pXZSBR-={G*rE|oeXO95#>cy6EEEo!z zGH3mZdsGX-%y09DHq-x2v2T$UaQjWd9^^?d-A3P4K*En2GZr^V$ZaBK^2OC5Dt z7AClKvVF&KUGKrq^BVlt)zN^lw$*Oe^ebunz%Ke1OZZd^lhjV<05gD^zksxtI5?ET zR=pDv!*U#z1?=px2GOn+S>{go@3yL(eX^R`)IXp=ZK*~{vmV*&QVN_c-8J@?`drp6 z$n8G#tQ14Tdv{U&yXBW9GhD{IHd1ZHt;*jK`R1n26nqn(@y|+XP{lLHCQb!QyxP_^ zQ9)Ew3uU&w41MTd`}5BE4_f6$2&1X-7wz&gee+Ub;){+pyXW|%*a-NT<2qZo^cs> z)o`M{}}Re3(c z-DG_7ZdtNZe=&!YFwo*m1%lx}JBT4+-a-GlGfb(&z%%hJBs2t`Jr}ta=6 zV1o#bDXbe)Wta)sC1P!2=$0aj{Ws%CpOq9@|8!{VT53K=D7wQ_&m>kU-V4>xOX{-k z_qNpZyCkIUTWy==w}yvR@MOy4e&VF*_|7|awRW9~-{Z_oYvaGs*cm!HSF()il~0+D zVm03Q%VkH!wh=9so9lDCQV8MxHH;};C!7rms`=Jx;UE4^FEnnZ zSMRrSg%Uh8M{E+)a+Z{Mn>51|Rq31)QGAQA6D|DGbm_Q7v@)sHqb@5p=EYAG$2@R1 zfQ76U&l86tNmx7>oL)&X39BplBO=_n`31}B$CwVo0FAnE$s-!{G+>S(&SHnj-sv97A!sBii0 zhKa26D^s_nF7=_a7qHAVB!R=NjceDmg%YDfQ)RVQ&bN|8TJMD-)a~F2#hrTcuh}zH zR-~(I#Ajh&vJTBCi!QFS=}Whvu-@oKbV-C&XoDWv*qehv#r%OI+gpOY6(LL=GovMu2!R(QIX2tgjuZMxOBA)sl6Se8rF8W}Ed^Z;weKCT=kB8TKSk`?RW@pG zAp)p>UKrdus37HMd=aV|mR#_geeL!3PFy@yAGEjuVFk=%aNMiS8so*D(Ay?uz(C8m ztNNUdF^VBmNBQUCT&H5Dr<((_WqB7N`IV7OMdRBq{}P@WL60GoHavCj7WgEi20Vt1 z)pi-4VMLELn6r#+7(9e)KesFuxQe+sbB!_M9B8iS&5km0+yw?$jW{rtF@obCZaOhS z(_0^`u-M@|5EDYyV{QB;&s7o?F^pFe<E|jOQ}df zBp3(6$I?&-c9zor{(D7d$vfk7GXA2cL&riPbRE>=m1~!N7W^F&PB|NXYDAq&$^7Y@ zp>vhhC64U756~sojbgUI{h|9!9vgyXufakHH;>Hvg}0WLbmYb8aWu5kl%j(2ylRlL z0%E9Jk0>cWXZ|$s94t8yn`PmkXIxqoYj{Psl^po%^?E*ai2XsJZVhJj$v#=OAD}9U zmB-$8_%PUxF0d5Z&n&-0@ zOFxT(6=3Tl|Mj^RQhT-fNK3L!6pe~7Q*+w*GFAH_7Fbk1w9#{AM z&8i%wIO?{C%>5w+%Qb9-Thqbc^PzC*@1NTzW1X%^Za%fFXyXzttk3+?LeBoKF`quY zsAwv0XM}V84Zrzaxmpyx-l-30gP!FCz4I-XPNg!C0Er%G;7y~R9a+;J!;&^~?gPx! zNq+j1swmCPO9t*aZeWrG(9YW{1CCSuxp`+i`Af4hy+{3+L!vI|b%R+_Q;!HeQLQ*Q z?n!Y`C5Y?IYv_Q$GHlCn56NTF(*g2f)$d5Soo@%IQi7?EmkQXeJK?CBQWqi_hH4Nk9vGNizG9QUGv`pMQZFNTg! zo8<{Ayj(Z?n+)%6bNN1Y)~svz=Gf+mCPL94gHcZ{+iG2J^9vA zX6IxR>n$hILPjp*@kU`{)0U_-)5?P}I-%NGJ zZ-3L^)mlgo{jes749?7MW>Uimsk#X2-qow$&golM+V?R1Tgg%ypf9!Iu2k;j_`6y? zt~V%c35k-RYOJ+3V&GMx(CCp*47J#OgIQA4$ZlPk)G4$?^{wI$|LU05dDcF+&QrAp z@3$zkw?}M|&B#X+WPAv8n=`d0rM+F0yoqVs9C|$@W z7NrvYT%WrZ)WCO%JPnk`6T8(6|WDCz17noauAYT+0aI4*3=PYYw0T= zI}qBh@4-ms&Z+2fteQ4v4X(M-3JKcyFT&s=574LO!|;J99?SAy(Uhd5Z5YczB*k??JCXvo5Y zbWbwlcMnI)xo!uBv`LX(_<)_LSJa`vi?f!_bNwK`6#17v$G#BJHRb44%1#`<;Rh}0 zD#rnWAb$;4tUD%^NdW=wJdFGt0)kx)vT=$rVI8D*@vG|I(t2f(2;XWCoXG{$4&^F0 zv`YpYCS}8;|L)-T(Z^-1iKb@pm0NZ;DL(bVI3jp-D6js-G{}rxbCjHzWyAcWjVMt| z30I|Mz_sLvq#je5@;zBx{5aYhdSR_%G(xq%J0Zed2Q0qfPyq7x2bia;89I2E{eXyI z%KC4JP;(?P<&*i@c81@krY%XRDy*62u>WP}6GP;uEWh*WhxWp#>>)nZTo0ciP_s$P zcS)zS&DF7u5V8w^U$T@KgambJ<0zuEO&U^Uokm*&rewpd!a|$Mk*K>V)mkg+{whgS>Z0U?23hO|zySHGMA&eV%Mp~?xo3=u z-VTz(#)4L^mWQID8q8yYW!9oz9*~mp+&giG-zRvQuz~yc*BsgfRd~8)o*<8#=XHB! z2r8jrWLu-QMf*;<=ji9cN%9lgd49LY`9^d15Bf6R4q^(Tk8<2lo(&2WNJojZBB>x# z;7_j>`@FB zRpwRn>R-e-Iixl;IwZo4lG_FuT?~d}29q z!R=(~>@!f)OiU%cl`4@W%ed8mcn03`G)mLInVfcpG~g42^%0>^sxuW z6>y9mftL0WvaWRi@N(!?h9o%&*FtyX*p7wO*x)I+VZ;%%leTH242^{oWFf)c?)w)c z(!e_HW5UuN6u45?s2LF&IBb91OHb~$RF@C;7is{hB*3^aGDvnfYu!rdh9CwuEOBw{ z_a^M$lau(?+|?QXJ$FPCd-n>1!WUe^dzp=X7M9<2%oa+!mho?tzr|KGJ;F)X93>SzJj28YbqfMclI!#1Y*AD1WNA-&z&CL=%!~} zqP=#Wqw*;PqsRX~tE^x&D#GLZO+?^sRE|oob3A~zAj_Cx4|?&B67`UgK?igsPu#&E zZXqb1Bcu{9(Ky%sN&ELCr;!WYpS%8UTlWxs2t)SDduFK@@L!y7E-a@q|eJ% zbRgKJQ+yWjC1j**rcj753S1~wW8|dz5&APkoUwWCYVYND{}VnAqdUpO94r2+4=e|x zPm)5oB6vKXZ?7 zMFzs3I6-1^NO;nvlNknKvc10?SeE=KHuzADTUwkZP-cGDA3YEmyazYR>5+=q(Y}wG zn=HD7RC&PJ$rtDOfU$v)8>ohw$Es8U1eT)(@oFL(5}*_oeAoCd!Ko`b`w$w<-I@R? zT2FomoSRw%H1Y=?1O@pYm_GWn)+(fH-cjE|?>-zm@vsjRo{jMDnURUB>Lq0mM|uBn zZyjMWO4{<-7Rb7x>KVC(@izsLOrZnl>&7n^w+)YTw(CRt(2v)uT)rm;N@R!#%E;)? z`HR$I+*wVLW}l$bA23VGSAOHse0A<*3VIp$qr&9 z>P817wx(o13rc0c46u^}>o4;CQk>~EYc`+k#43s+4wq3Wlv^UXqBL5mvC7jfFApp7$v`aARv9&+#lAZp1P7(4Zm~Eu{i-$7hs|S9!e&_P-{1>@$hFEo(2R!U&u$Xy}w&z_*eECtj zHJqm=w5~9o3VaWGn;+r45J#Ogz2}&?cP{G>NDH{C)5+U$yYFAidB5T|h?hDyPM8Gg zIrBXGGg8k;P^ToHCp=TEAE6fFXSPw?I)4SE$?Ifp=8WFBec?R+d^Fo>imoibh?GbM z8MW44OW$DCo|vq18}ew8<`glhOsOIf;DtSB^BZqExcTfktCm6qmeyI|HxvCcNY#}U z-Baa%S3Vtb11tpJI|H30pbs@**6A59_OWlx6Kd4~U88 z7p?_5D6Fc-8dMGrrd+ zjdhz|e@KKo2I>=3%6>2H&@7-U7huJ8%vVlJe9F0^v9+do>C zfq$y%H~a#8^Ib_#^Sz|%j-=1Fr`EfmFHd_w!I2wSwhgnC$Uhy)8@ zAci@`{j=3SO;!J zwI=>fOhXkoQj9EyEwbk9^qYr?`EQzDbP?V!gmD#z2^7O$8$Utg1EuCyz*tYwk|gW< z!Nq^RbGbzMtOMT*64B-Lq57oe6)e5H!`quyjduL%*ul&RQp5fvqe|F$@Yj!Mfi`>z z!~lT!-OIkZr2&uKr(uYf8!#xw;yjg5!lBR7keFm4*P1`~D;`gap);ILB%*X*C5zaI zdFnbkQFn-sxgVz|dd>C)g@dt!8D)wDJ+y1P4DlU03dX&(E~D8QzN)_jv~N2orZ)*e zGli>y#}Ty-3+m)Xh8ALY5PtP~(AWz+UwD}toHMW+ zNSFLCDdHTMsZf^9W0>$Z_HiemlO?1lVdQXHYYs9!L%Na!M`Yh+-3zi85K(W*O>Nc$ zJ^B6m!%=L4`!tqwy&IQ->$@Q!k!Lh%)t4Ujk!Eb$+tzk-#})JRgs!@pA&kI91kvm0 zDx&k=kDLPUTrMbb$)Y}VSPAJit!5_H_k^Q`9$QC~=>cSlFqI1sR1OPxC4{Fu`xDRl zW|LR>e21Z&_B@^h#`mzNpmHM=u}Wb@iY7gE#iL#oC~p6vNCl8_DCk?zW8yzj#KAH5UGVuv z<;$DxPHjGPK#HqsIrEf4k>f0BsA}^A9PV6T+|5$^R_OH1Y;)l+J%uktqQ@IE_ltX+ zek_3$cI)U-)(6(g2V1w`Yh1Fw?~mi%-uFd*-knO}+H)H%ZlSBUv?~;!SSbDW|6;hH zWi~XsVq~j1n~hUiRK7V#l7|G?c!}gO(qDJc$KagkBtJ6II*Fh~jw1zdU%v%25(vA# z^mW$f$kN8=Rg{g;PivB+&N$xAA9a>rNure3dO!YoaAe@uG1`S_BGAFI`}}G&pgrP| z{Xui~1OPe(=lo7O`qe>vL{K;kCvX&{Te6FnLf`@c2`FZf4AQ&E3w*B+vg)JrkN4v) z4c+Ha-e^!>&@$0-@!s1Yccsla;V+00t> zs`!zH!I0aE;aF!sHgAbCFr<%u&OX?hT(IiGlhej6bC{WRo7Srm~k;b#k*etcoE z&A&Q56W6E>?h9pduXX<|;ama2?f8`zBs6#kHXIc(|9dBZPmb}`O}I%Xl+bU9Byb_! z?q%j;O2D^q)q%i@>DAX<%LlQ~S?pROoE8En3pUXtKtnI9QX8bMcw){U^i)v-87_xf z*TsfTh7zYh_<}w{Xe=dj!H~bBp#xa%o0wQSxOl0T{x_jaM z4~|)H(V_RX%hFnX0{4uV8l#5pcYrdm@;efF*5+h(4NJ^(-vRPE0<0F`BGxuO-*tf> z3}bQa^1LhE{1b%Pvdiy~3-d{NZD>M0u&Bu=z$1{gEFFyPG;PFBnAo2ULD1e+&hhfp zdHu&qV{S4(7Re30_j$>2p$oB)Wu_JC3C3eBLeZb~9(6f;UDGU3_XE8Lu4vrEl6))n z92sJ}tb%sqb#SF3bXmY(&G?uxT3_WlUpApyzWILuML@d0%Ug!! zSg>x+;JJuDaR?(Z55B0cl?Y43%OZ!^3{G6E2Cdu|GRY?0XKEE(>qf3p&@7F|PUFpLyMf%_t^wsX2 zp7O}g8bbN{2Eh0K*lWYjT7gR!=nRhDQblvIkAj@TMt75-Xb?a^gn$*Lg_L`>L^Su0 zRko|SQT-p>@~^K15I%_t1GXqCg2CC1C~N%1s1$O{aq}&!!iLbT{PVrkoE2Ku8<=MB z0lB$XWS(qu03s9%8s{QiES2p8Ey1eZ`V-lgpie>`(?gO5R%w{RlraGQ3?xh~LZR`i z;T~YwBH!)KvvW3<8qKn^>0AyI28RysP|OM?#M7PVcScGYLSPscR14Ctk=F%qb`Yu! zUXQ>&{@uCl(d%!t6JN7JoOm!`;_p$VS&%CcDtGCb%IZ|Ufwi95@~cC{EZ$L*R7dP< zb^|=*|G9KW!=ul(!mnG~Z0gR&hL7gjqiEi09=K<4hsExZ(xBX?FJ2p$VH1z`u^wxk z6Xr>;ZkI{lFPs2^0KB2@uYS#M5tTocGg$)gj>;a7N(YZ0E56Q|!lMQwi{}I|NmNV! zRrOywxxcJ+YEs&T3M0Ax2Mi>ncdt9jTn};xuA?!23AJv2hU;y^^iyCrP!{-*iT^U0 z1+9q5F-r*{#j+*vvtDvh?@*BGt5eGQ?((xk*>2(Yn3R4l>pVWO=*ZdF83TH`kFHSZIHP92 zCnbRNM76o0a-hWj}JKo&W+~>}DKeR`L9{3$1^S zO%uc`8(=`JOh-9IO!#!Gj=h{-mc;4r(-^an)+cNM0NC}&sV^M7Nm$GzPIQjpy1CI7 z`%rZlR>#m*pfOGgJ6K=Vp$}OVg@%c&zqk{#1Yr9d>&7^zH3;GXH z07v&cXl=Af-JIW@FbF{_TRJJAS*mun$AecAt*l7kC46phx$3ti4Ccr1qb?*`Y|L#| zLW0=aqQ*@i!XnP)TJuRNaRI&@dtAgXkGTp(7s3APD@LZ$AAgc(?|z6y_)1MbO}V`a&~M%w z@MoNW)|snW?Ew%o=`*<~&*|7|+e_ZpOfQeYU9ec=aH*6r+P_+cJ8rq6xjm67GHvIn z#iQ2-h{zk5TVJm`vj+@Cso$gZ6)o^-&<23A(;zo6AMYY7QTg-WZOX$`%YO;CZI@sI zA)%%3~oy0ardavZu|53l!M0t@pMkoO(gyw5d!HCEFZ*Ded@X?K}Kkx zY$PbYEnO)$#^s_pJ%@4qf)?r&KJb3bS@)lE`wr+!>?76!H(j(JD>6c-=LLeKeqg3S zNxn#{T{;A9e$(d|%t=%CFWZ3L(=Vv%pAWYq3!`($rR^!}D~*F1@cD-Nu1xE>!tO3M zdun^D-zq;dG%l;`vU+vQCQ6lK%fW%b54figbbBICR28kZ7?COVI}4Hl!elPh^~OTY zY<@DkiZqEvP_zE7*())IuVw|Tq_r(=qP63`olje8?7_!ErbeE>yU#LdOiDQDr+0jT7PjO=%33;M@2c@E69YCg9x0s80B)>xlGSrSVSNBCia8(JQjN%H+7< z>`hqRu^H3q_);e5$R;N8Ee^Jo;bSFxGzJSKQFsKlcBOXp{xnXSuS9z>ECN*T)X)`_dTIU-2dWw z)8ZG0`S1D!&@4GsG(i0XtN$8jKSTF*MenMRb}7VpW}Dk~+QB*{O>$``_M&d0fZ%96 zZmrEnwxt9IAh!Nu01kC2Sb)%@8#JI!tk1GqL#2AY`WH3qez~$v4l-fohSCNWk5@T!O zW5ho=MWLuz;Y5!bZ5rA;Q~^Q&BypWAY%2_BZ6ly|PXY5unkgS`Wulr`hk<<5?0A!X+w|6gksbsCNpLy3QwHUTgl105%dD_^{TgbFlKhRy z&$Jp_a9e4Uh|9oi9I>x`UjWn`YeAxg3;!B@-8*-O?vjS2S<{q7OpJcGUnY!+6>+l8 zL=K)-?>}=^Vx4JikJ?R8<}hAPsBO-mjUaV<=yLQ-m#b1I+_UUk z6RPD|DaujrHsXJX2!~6#+sUWTpn7YuyUOO*-t!o9ZJ#aHPV-D|w|imp;XYV}s(2(s zLYcvr+XUhnum%hWqm{nS!JAx#L>S z3}R(N!W{74{?p7&+O+_oMod+yKKCjc;7lC-EHNp6<|<^aMV32XSnF+Y#VZTO$uCuZ zVJzA_4>$f%0OcU&h}D2&5pUnU0`Z6a`#vb*Jlme#Eu4|WWq%Sq$RUrP$0e z?sv{PQSgoVfHC6DE)LzNZs=P(yQ3dEt0{iAM4w_$WsP96Knhv9T}Pr>g~YUIom?pf zc8yOIom3a;nK%t-U#CR=ctX5!_RVca^4YrznNSf1)-8VPzNqA5Xg{3AMnhs zA|Z{|c5XB*t#fp}M%wzW)gA6q@qN|t^%_LyhtfNWLZI8nOy3}$TT7B>Q$nk| z)BpmBzW)@`VTe?gsci%h+Q9?Fa`SrN?=D|}Fd*E2cR0QH&|u3wG(*HQ+QDS%tCRP0 z{p)pSgCEZ~PJL)?62LJf;rRu}|l9=XMU%*Pb=<`m0r$ zqYmIa?Wlf*yYFa;T!0GDGLhU`zQg!yHLlFL{Q2l9DB@XgVd>ijjkjo9h!z4$MaOSx zR0e7cTK3`451t4O;p^A#)$EMrx}898*q9avD%SyO8{OjLpMv-sFN0|LYT7hfM-Z=K zX~T8_#VmQx&+VB8Em2o)5f5AXdk5a_fh$73ualY zjw|zM!soSYa(w1(+M>A@FO!JNL zaW=W@yc6KD`y`lCUF%K#)BmTBTn;^;WCE5KrGR+a2!qY*;lVP6vT>b<(Y>GCT7Eu>Ph`muuBH?Wc*9Yd!Qo6WiQecFgTWiHX!&VhU}N~B22zRf zte^|L)I$YlKAm@jsft*5xc*=q%Cpqc{S|k2m2QS`@$?j6K(wfX zdIb>dh&r-Ug0iR6#&Wkh8km#fxo_13PClm>J_$xu9q-1&(o^8uJM-JqQocV;COI#T zp{K4smns#akJz4R!)qJ*Osv7lQRE@NGVKYAe#$mr-v&G{SCBy;LYTAzoXa13vyydY zL9>v7W&NKI$I(-u@}bDR-B(i=(qcW{ekCsRb}FaE)`XIEmK@mhCsEyWa(_gA=AjJw zQMNZ9VW)MrDYj3D$|XmZfB_J@dJ^<|uO_2Q!M=s}@MruP8}+|$hC>T?Ul1Li>vK3# z6gRwlHS0AW$?vMVYF5?6?;GVm)6Otj5`gibft4|t7~IG`uMXBDHzaXy-BFvL@O@-E zD_r%QqKN2OD&U=@G@t@n7WRf?{dl4B-BMa-`K(*jU^&soi}Ulj2XoX2gEe@c^D^SKyULlcBdTJq4A>1^1b3+epR-D}P;`R^F_lIC&zk2mQ2>D< zUd#)&SOOC1%%|L#Z*LiLr`!DyM#<*z^P}5|qbUd5T{U2|E$Jk?pX%*l`7$a`mv(H| zxMmv?M>lc$ZUhEGrYQ=zcr(kbkwvi>jj8?A&@Ltbwmrf-deb(&;aUTN@$#j=zP8ip z3=)S;Bclf8hbpgLSVkM~95i%0piz;y3(NQ1gs4R2Epif=w!x38KvRqx=!Eu~z!u)X^>^`p_B3Z;1=#Foby zNQfxX-dekse&z4Ko~bygm;6HNQ?Q%XpNK19s`9_41ZK?tl3J%oXA8dltrN2CxKf{4 zqfu>#1={O0A?&E(0stU%?N+igZ0!%aCoI7PFwKevu>K}}qz}=8H9oSc51a9}oEW}y z*P%^I)QyWz=vwxwfh(_LMgk#-eel4tfAEs)qOS9E?3*`DUKWpDbsQ3`i>CS^ZKX2a zb8<#FcY~*qEu-wFufQGrl^?O!1-vZLelH(6gAiH(LY8FJYK)s3^mJS3K#gw*7>8x? zJvd2YZK*;Ka9X_@|J`+e)xuj<*=UyX;nCfaWUz(EHn0PBaJIN zW`kQUvmEA*uNx(0rLj%`hly;?&t zQFnLrWYp-ZYD5G;;dBhV{(*Fdpa2F|663T7cB6WIq8T{PypcX`dq=C+KQ;vA9*BFg z2B_+UzT6#<1tW)2tk*Si=7vb*I4!R2seLCgaK;?HaH5Wduree z4c$(w$*YSJLKQPPaXo3OuBjd=0A+r6KG{0VKN3zmFlj9?+2)_SmoyCQ5@Gf5wX^hjmy;UtJQ9mM|J~ zMBjSz?08<3HI|Cl%6#wNyu`f4j!?UKWQ0C|$V4G5U=v4pukl3{L5ot)>J4RV_FrqT zne@Ry<$5t^z*F!}cme@Bii;pK-#LqWvDC^nGi+bN0RYvgYZVDW@<~SAC0iKV*I7oqA4=%tjk_#cIcL_FT|^EC!yc z!VTWF*JuDp>arlSgKKx7kKOHbG)U6-gwwe}@uW>#<4xRO>c(#6gb%X|;M2aJhFVmB zKsWhpK5{aX_vt$eLfj>`pOD?L>LUHPsGcO*qFkz^!5M{K;^FOa*54>1^{;m*@qi=Dn7|%mMyeVG&hx-AL(?@ zKf(9f-{n87*C$$F?+g+h$&e^6q1F$;2Fq%jq>@)_sNp|#gpMyy@2BGn{t-(3%D?aT z`<(2VR#VcZY+@sJi-Gk%$rd%@;-{i7&`>zE0MYdWS!ojEpK#PSf)Lqi7N|(bGJKBN z2}}u*CvD@Q(}jj-wpJWxnZ$b4qEfOW2UGPu1&2Z-I$AqIVN?-%zp>U!&UcQ4auq-2U$Lm%)EXugO7h7la`rEGZdm^ zFUz)brQWTk(%~+$dpN>9^~o%FmmXQzyfiKL7!Sp?efB8Rmc0M*>LF~06nnm}kFWVT z60x&oObpEiWrH8f<>d}v>JjPqmoGJWd5RD(i#CY@)uKoyK^OD)k(PzzOz3{nU29LT z005%Mg_4h@@PcXj^z`BK62a43?r-;fJ1dX|AOLI?$IJ6Pd{zlj%^PUR;&i$E))aq- zgN6#wekmHIEcMhr&D>SB_4#F5fVhC-N>Cl^DVuQDO0<5nAk8 zxvI*Bp6sVHrPng*n@q*B`Jvq6h;_n1ZV*k}UdJkg9*@fU6#wVru6P&4(FRR~Y^|VO&OTSx6D8X<(jJZ%;U4!*aTW6|KdUBD*fCwNH z`Xug={WbS_p@GqgJWXPKtIdLUneHcdknzAAe6CjQiKIQP> z%NjKd&{YVaRdz$3HC*j#LW?5H_`p><7uC3N7c6b8AC z_e8opdM5+4;t_?%xG@kG)?U$+DF51=FAWaGjK6(|dhag-gCp_s7s=#2n}0}Tb7z{2 zCNc(KPHwqAO+%7c8BUGI9AyX+rF`RK2`5ajcYggp2{VAeJr0N-V{)&C-21XFE9MX5 zoLU+Fgdy&6>BY6kf2GtveRi{&bG~FD>;EYM5gc5va2+VbiyAxmV2W<#`^rvkp74Iu zNnnc2yfp?2k4bgH>bifa?J3c7Zcg&M{)Y&+wCAp}+`b7_Sp?w3X+E|^fBJE;_VPWz zvN)%u@YLjJsY4ARK!juQv(&P?9s1=522a)=z(E^@#Hg1iH`h(Ah_yNT=LPCDf+-cX zzoE(hv@@3fH}+RZV?99hct=Oia#Y_@W&d+gC_XGxUtvwsxuj{|rbx#E%PaAe4;l)Z zIzWbVPAXKD>(ZppWeam*CVvUaJNT<*|8F0#b7%S=9QxrgSKVg)--e9M<%vYJB?@Ph zZEEe4An2n^^KZ3MKWYCN!y5mBA0X8hFIT=u%htOF^I_byJ$Olmxxm-+M6bac71PLt zQSUDdT}O!gGUaOPEH+0F&`buM10sxh|Fqw_O1gO`GxwZL&l7@X5#uh`8(yoziJm}= zLmFdmkNaZUZ6Z}Kt?N=(w6>G=FGv_x4y5Zdz_ArkD%>v84Z>)DzwwIj=>3J?sdk`? zU3OG7(-Y7o8l1HTYvI%Oo_TS<(_2M;VXji2)h5rC*EaG<=H?+|=}J%-n_>Ane6wDi zGKS)1w(8x}Wp+zZjsXytS;V;U=MJlFCi1dQGDjm{qCX|!wN7S) zH@0jY*3{AWiF%K{_O>7c!C_7EckXF?DBmBfEEW6hU?Kzwu2QA<(A1tIYxe$%04k1z zO#WJ)l2a!7A&Kva{nun@nt1hLhb{>Q1@3VS!o zRSy0j=_0~+AeJN|)rRy}_+g5sZdXL)B9E?lhc`&pbKyInvc0yx$GIUN|@ zw9g<vI4Z0S~Q<8-SO`b3zr8F&bWGRUS0fbD|jP8jC$ zFn>c_fu7KC-4PmCOX7sUZ@g6BunW0JFBd_z;3eOPfCz#7#psPn{v|vzJc+TWHAl`S z;)aAu5B5@nJgbaEaE!(s=VgK)rBOhV#FI{szlY4A`1GQ`nMu` zT!yir7$+yc1b;b4&80b~>pq)1ovwpRGFw zL)zSpU+5d#CW_AO&FT(OG{w33IFdh((Qur><1BE{i2ijz$QUCwSKH&d`u@MnM^KJx&4*9)XD_#6x<>N z@MQh*4hH`eFX50x$wst5x8NUV@`@K8lfyGKf^jtT{r?fhjP~5LA4aLJt+v^PkJcNHwX00A=2qvzk zx7azLLqUqSHY1E`EY6*Vuc=2%L0+|2?o2?3v9v2wM4E5DZBzt4*a%$CBQvSE?LUv` zyPKY^@GVCjQtQgG93f(eJp_<~fqVCP^8ALUhnY)Px9!K_UP!hmzq2j?0WB7wH*GYI zbkm})SF0IG=O<7_<03ZvFF!MFTT4${ zwel8sGOKu%%!e?<-^{N@KAsD+Gg&hh@qGrJL^B+iz^PUMvJ1bj(5R!n-{ApB!2m_c zK8klTKSNPW@kI8g7bur5IbiSGOf9f>dz{GLzK6}ay~)&&Z|~Z`|3$druxda_Puh9J z(piQfu^dbBrJ56|)V*v%*_IyQqn1X=aJlsMd<3%fuB2mtj@2W;c^{juoH z29ZY9kDqNldkpXM%&OQAAoOaZSRQl}6IIinuSGI?`~8{Dg27DPxzI+?3$l0;L1({h z%U)-_19aME5gl60qAh*Jj<#w9GRkn743{M%UP{OlVC{BkI^qNYm_UF@V%btRB9&UV zZ&YC3Vg@Brxk@JVY0ss-16k*CH~?C$yJxrWl}_E_P-m?naL2p&Ixo8xy;e^ujE z46AOq#(`Z~%Sa|6hiTs62xbd@28tJXdH1El>h6~3D)5(fO)GtEO`PL=pO!{-@Xz$n zn?oepF2*7`aZ+^Ys!ur@t`xO?u?XK*S}UZLhaZnK3b41HlFIhNPGm5wx=yt;Ke6}^8cd(gton7LZKNb8-D3<{F{!hH$xJ%NEY`2)%>GuJ@B zg1}tcvc5wEFbX!>=uqdwr}u`-D(Lujnw8Yhr;*GvF^b1%W$fFRNPpin>H4l_Y(s>c z9JKZSZN&)R--LBZRaAdB0V$yIDE-BFTQuwLrKj~^2*5qJ7*b8teEX~r)0Xnom{~%} zx?1CLHRk$E{?Wvd@Gw=CozmSVVp6jqU`^u}h5J*5SFrlbH6ANs5rCuD)0RgST3K%O zG?%?{Csqv6K5HqMpAr`$77>*&%$C{M(IJ86x(}X;4I8dL*U)2+2&dJK-`HlcS&pC>=cT_1MOqf@1c7tZRiKq2LMfGquyOldf3Wek0h_ko7!28cm6nEaR03bk* z5j(C%N?(sw*xpl1NXV?AAAv zOy$%Fd6l_4tQ;=&JH<&j7p=?uq7qM$|ADMqTlME@%iVInCh{`i1&6*xtT=XF)pN}7 zC+IjwoD6`cf!)!^d+z9#*&}umanFHc@*Tw#V*lMUe;M(x^nSVB%(pRN_M5UsW<4=^4hl zfF4*ED~;mD{HS*(gtalou*ls-3zB@l;16=-$w-zc@-#XatYtA(1Tcb8mf~^@x$X`A zK|}Q@rxzJvp#Wb4g)!YQLjRM1j)H7<+hJdSKA%7`(H;4Q^$6p}?3Tc2c zW`fu=Dm!5jc=;3#tJsH80O`Qeg8-D|-?HM*@+z#6u_kzBh1jG#aAwF0@qR{JQXbGy zwwINT3W(MQT0Z9%SX^yaUxc1|eQFpjKFw0;RsQ}?&lwzc=4X4B`szD#D+!OgIpE!( zX7k@0P9J-2>3PEAj!(w-bj~_oH_=?MH3*J@f!UMi)xOz%sWf-jSPGrs2NtPSJ3Q_3 zWy3n}0+J)m7XTbU(s-|?Scbl23gLx?^XC%H36Ah+l!}hn!A8Lr+s}Yfq;@7fe$G8C zSu)ZglM!4ht$>1LY4%gT zeav)d425^CoAZH5XG2{as~>=ehwGY}S{ceSI2E~2j16BWkZjB2KB+0PY6;=T0f;XM zh5e=2Xu62>_Zc?-HI1M5QCIh_!;Cxf03hRckjKHsMYyf|~?v{O&%~m1c`rgCGvZ0uJL4CTV^kWpc5I=F6H` z#$jZ|>GxDQvSmc~h=>RpV8w#a&2EQUn%m@Kh2QRzmx;=n=s+?Ju*$6!J_42_egM`^ z8&0-`{TxV=n~RZz3*}7IDKe;LGk&!fv-AM)lJ^;d4)wFV@4Nwh8KB@SHe~9mLw?(& zUW{x(tSBV+sbO5805*Yrnj;gI->Rq{W#y+#3x%q}-M`qM)5H6|!dC*{Z#)IuC%v;PoYfGwd6>?4R#x;5+q56b9xu*w;%|H`& zxP&qPa>hTE33B#G89XIzI+NcjG2^`>GlU?;2QPIphW<{<(IgJCvko{ey6ldGrk^U( zuE(~T`FE^2@bcpcpwdV(Xii6I$3@QQh-10+pa2jLS}|NO@f7yal6kzXdd2o$Z^M(2 zKZ!S;D*s~raFdn6a{#F=(&yB%h zEA$Tw`va0W00PpOUvEyPY4nTo;ZGR={Yg#OX*r%op^^V-l~GiW$2lg$unv!GexF=c zuZ@EIkR=C~J*zd7g#!6WfGJz<6js11n5}Yf6H^U!`-+1^Ve}eyu-VT=WmtkLMC9pc~`Dp9XdxiQf28Tg! z&Uz@_WQf-$>doZJ>eLYg#6sMT!<={Z;Jr`c7|PzW_Oh`WkMSnraXqwrs&VeQdkh|y zyZ8KQuz1D9TDCVq1-tei>6uTnSO7Duv(?^@q8XFaq=!@lGcs9Q+?Cd8p_nCmVG;~N zHt7>6(V&J{VhBa?=VyC=#G8rHCAN!M_jmllnu5#@ci*!s?Pf?tKf&Eo>7TUc&z|dy zRdrZMqRt*U*u>H&BmfJCFN{;WL^og)8;MNm=b2VzWeZX$T8L;i)WC@=w* z1qmVrH`ld(X^`kBhCzG z!s(z&98;~938L5C`?bVXz{)5w{}h}?Iq_0FcYJ?YB9iGAar4Pr{0!$pK65oQpJQwu z&-+(E?;0$%rzz>NU;(@0Qvyd7yG6*qh5_`(y{IY8|f34!0S1_h7l@u zvT_-!5oxegu2qCXNjtThh!bVI`y)1?CBiKakc{HvZJ8C{{5no$lzP3%H+r%a_o?~$ zL`7gvnt0wO-m+Y}i@IN|x^$}_bZgzIvwB55Z?eH1aeDGX1xS^2j0QG&{ zX^bFH^~SX3{Yl7DLEmXA59UvE*Q9kf2iv_WA_J|d#mJ~r63P0C^Wz_B8ozbs#0t1g z-DBd`RF+3HRQ7r7`<}e6!D9cJLZChT3eEF?FkmAo_S<_BE44&>0f2p+m+nI&Z?%t| zG|cu8K!Em$5I`P1z|Hi=sf#hPbeZ3Th1v!Bv`ioX0000Opm7+Kt;-q`GO~)|>-w)` z{XXC)dDwIza_b=db$HZ^l74wzc3Fz zSzN$=hXNcu%#9!}i)eEb1qR?xLz8Rr;lsf4N2X#Og>r%`Ezav`YU);FzLASXft^QD|q_ zl_1!wVM_B^<^_nDn5LTLUcu?+A(mD%ve*eP29PBvWcr-WZ}xW3n~p`Q7=u{7WRL9d zuy!_JRKdhu&|0)f07lwkJ&brSUn|$o;!p7wQeR4mwspae-lTFnvCARgBgxn*9U!{` zPrztTihs%R3Xgxq82xb`ZvwEDGzjAgTUK1D^OdXVK8qRh^57w|O@Cix7Cg*pWMiXT zGKzfu(W@E%y8sd?xCZ`T0opa&5jZaQm6j^pe&-i$q&|iNzpoGImaJ>z``!Q9DtP=u zl@8XW`zAvj{tT@3It-&{7W>>QJj1Sj6f?l=q>@KM3)u6Yj~ApO)qGpMA3mhZ06eNk z8ZOLyn+ku@0R;J5ZX#G>;@ZB-E*QXOJn`pIAg1rW} zh}SIx{!U0Z1wJhpeCXiRivxjUhvl{d$oVA{tXGL@_x+>55iXNsJ5%v4I1@=1$L&ps zS8kv5+pjP4rgpLbf&}T0UZ);Q{Fr}L=Jw7?*8gS_bohCd(6XGgh+{gy1P~XvXPeXj ztRSGzCU2!FSBU~UJ{{JD%-5mjmUSa#d4RLo0^!d+GyDVZ%W{+IcGttIpYX&)b@2{ zg6)Hxk!!&GnJMqp#&CwC{gR1a3kdbYYRhSS{mXHe>HS7XVdSe|BXVrg0?leQSN>qa z{HSUApON^nMsFUxp0LI5b_vl6PlZdtl?hUK%sMF|x#)^%OzX{tuMjpwVTl8FULBhe zE3DT={;&C}o$yBzEJ->}@zJR(2pP3R-&u+>rU`e`DFgRBB-)?!-YM&T~^e^l&aAL+BA1Tmr&Lx$O01y?p z@`wnta1(o;jPqeYKmTUz8Gt73#9UrhbqBVQW710Q!PwGh<E&TTy60{&baCRh03!Tzl%u?h?txCGMm@k9LAsavUJK-w2OxTQao4#OQOZm zXv0N*&PDH1k^;b>B3W<*ss%pk=Vm|@0@S*X@Ro_^P!#nKs_TBeY=Oqx9uYF2hbEx+ zsHY?B7xboMvZ$iAN?Pc2_>QCVrs)$0giQ)aIecjDM0ZBsNz)g2sF%!$*l-=!n0vns zI~I#`o}d;lCtRfVA2#vSKGMC1i$$ziLy%y}XN_hj8N1putLtD?@M>=WwZM@9uy1ac zmLt~eF7hHFgb@vMo+0|c2Y`O}@hCY;4gN#3<>1kqF+-`S+{IxL+|i^c%onjW`82>n_Ve*_t#M42T(rqyTw0Sw7=i|Amk zZc{bK4;>6%KrQ|&gEHM24WERW2@!JpTAgQx>!dw#>mg&IJ$GXTfJ3PMl4q(WR`E*k zfM3!%3sz{a%*`{bUNWu^yI0bBWQ_9iZBEG%4WI6=R?QQ>?(N1L_GRM?w|3#qbN)J@$<;}k^DshpDcuYo>;^3Nivw|a|0R;2 zA~3a69saN4ji#qELEHoCx|mrsj|Nyc)kMFQAlC&k%j{v|T0%Ro)7%CKFQ4zEUizxM z*v`)L7;K^Bl7IZ^_;8Y}6y;x^L_)?P0R7iSX^v+Am-YP(t=Supd%R(szsa!Z9nbsz zXtk_QhOCBOtiT_$o&x8$$ylhB2w&EhMdMcHiO-EL zJ>8MbE55Vb?DWU&H3B_SRsjNPV|>usEDsyPB6qp5E{?qsjp#rUDbl2#u27#Q*#3vud(!@;S`Ht{#Gc5J8z_2**dW5ly5 zaI;hcwXg@j3Jjl=ex9m_c}eY~ zxlF%z@Q!2}ordPQaLMJ$^t-RvC-&t9kAo5M|0rXN>;(HCb`B2uSJR4NTZ6Z!;;0Wp z<7zE{0GZF*_F2{g#8#tl1V0oU1*|`q_%&HXn2nq{5sX&51(PU`m%^u{HNdskJIEE9 zOMp4Q5uwcbZ_W08 zHBt)w8<|pB-4#3Fx0&rcqnnzh03dk^CvVa8?1v2~MF+3e28+%3<#;pXXKOL?+oPF| zP#k?)ZM=qo`fKN8lJq^_5#u>|$2WP0%{-6t&{Mfu!K(E|_U#PFsn2Ga`lb6q1gCq-x6wT7M2phyd#C%eK5a#!kP@PQx zz)&zh7Kr`zNt^3z!KU%qcB=b>>yUUN3P`3hoD|KJ4!b)#eaM&|{uK20`lt2Q@I2)} z+N9sDo`7Oh^yn!^eTOoA+LFlV%ydcW(Dq&`iGQ)%c&+Qg)|=XC?slgYJiU|$p3J)} zZ+~X^r%Ng6)I7vyqv3wjNQ4E%+qVdOYKU%#+4ZHN1 zHl>j9K_PJVcrpF7Dt1`v+3j7d&c*}oaTAaXK@R+i8%kRiBdQVJ!8qRj5ysvYP%D&k{K@mZ%uIfN@u!nVtWSfRE3 z#q$v(z;Uzi^8he8`2U*4PSQ5?!x9DdK{{w+sb zGmhE;Qqi~!{shiHB_-=Huk&kADBySFYRoYE;I%&3m=GwNksb}iCI+Y9=~)-g)Bi_x z4GoLzpJ{Dcs(ZZ*v#DbfO|jLJ6Hd#)>+jI1qg}ogH^RqKe(igCp=zWnyzU-I{d-y1#=9|8^Gcir2tgF1DVzE|#=ICAh!>09PF@Z)AJ3 z%H8v8@NjYqoBMv(rml#9LK;Tf;?8<$djonn{<5>3fWw-Cs}w$Oc@pF!)rV!Pf!!zV zLBJdsY}&uwP!&$rL#KBIo1xjQ^B{xLNwI@_z`|lJs#TI0Wd_Y|S$uoG zw_hLrj70&s^^iaQ*;TH2uhY=}b~2gqQA+k*ai?=YHaf2E3_MfamADw&G{DJtGoo`1 z?!^EC70i6r2uwyvzzUnFLrBJDH1#nk&r9m={y*Jzejdks6Xr1FeRV^jCXs} z9uyeDeSgMED^V-saC6t%mzXJ}Z~#6xB(xG(aY19CZk6xz(fb%C(LJN1^~|@s($Tq9 zC#L3sFl(h6_iwme-HIZSvhH{Jk^=~Cd01pfPQx(r`$Dv6U88cv0W|1r^qh?Cb9bEx z1#<0jaO=J|zSKQoy_4*8aOY0O+}-AwXxbE3(`W8<(xd%D06_pwH!HBw?0ok1kVZgW zQ{tqIJv}E80Mn>$czp&ZVO<~tTLK!#rl7Z^FVqPKn9MjW9WN?L556&xP-2DTo1nYH?d3{dm|;`U8f4K8MS6sXXw6d(}a;vO~#t(uxuauMrK@gi&v`JLt*9 zh>zI7b?CD4%={#!5`WZu%fZ^L-6MXNFT7VOkB|ob_AyW;eb8XSW2BBo7hU@CVps6v&+92a1{vZKGC3>X-*@69bWk*nFBk``=eDdyejkT{3c^|&42 z=~LG0J@>yx2!YF$%cQs9w7E6wmwzI)+HDU@hQFI8m0=Gj`!tWH;aqvUgnX`c^tH2w z03taScD5EMGVPoJ?O<*4KbKjW&Hz3|`DCvg+{GbS?HHynqJPZ)91XJ72NbJ&?%9*>3( z&^OLb1K(^u%vaY~l{if5vlcckx8PyiaU{T;2)SWC(;@WPb|}>wGk^gDpWB-!B+*;O z=*L@jysIEe$B>%##sD|KWUd{A5xpUjf3YhV!vD%`C#)-(5o+o&eE_!e4YNoVq8M); zBeWDv0Wt|XBQ(j;3$Cum0NN|_(Hj3^d8Pn@0vt*k%Wk4Y;XJ3n00BomdQd7Y&3oC< z5D>-y4gZhHVfpST;>y8yc+o$l`FDJPRPdfl5dm)L(o8~t!NmJ-*-y4@WBZ5zh_V5# z01HmIDzXy#TvnC0s_Sqio&yzm(S{G@XnbeNSQ_FqTsKVma!v)q5>Jf#+6_ABy;lX5 zEL)UoF}2xP_<%_!RQ&l#1x$1dk(kHvmhEcS23eJ}wZLTeoHVbXP8yLxac4Grdq1<0 zfDO9>Qlv?Z!qQn0Te!k&TXdi1l5B_Y7h=LwUZcAx-d!YVvxqIv!Yu>v!{@0melvD2 zb}pVa&xqvsz3iZ4t<>N0Y{DRr09tBxV$aj7)07B}-u|jCi%29{zJO)9*fp~+mes?- zAnWTZkuy0Lqfy5dDOK!TjsI%2{F&S&PW@*|*YF3Dzt~&rzhL!PVef26tW>^9tDKgs z*WSOnjWccsHl$q9%kpeK%hEShy=lY<95k%g=7v{Ah`kKVLsci%9TO30vg=Ppt7kcL z?R|}=TK-@jJR4qXgGxO0-aQQ)0We|xPL68pE}`4zcn-fhGvB$8DB0XhpxefC&Cmx8 zD_Kb0!~ne{7e5ro7h|CJkYZ(MN}6eS;f?NZ6Q{@g?)TNGh5h z_*IwELc-G5W-p@P8NSkGu77v>H=O7h7h*{d;>PCz8&qjMa(G2jky4{Nw^XP<0Dv>M2@(X~?4to6k`3#EZL)k@aR#BAvT zx!FVA8dF#FKLqU~L;wunC>UvOM;9Xr1o90K2pfm&5JNLTC*FF69}*VRb)lUi^!J@} z{mi*HNzi%s&JmjHE^S?IU;B%Z-n@o=#3UUSB_f#Cebn1dMTbNEmppBy!@IrL&yM!E zL=N~pdpWg!h8-`oCy>F~6=hA+cTE3K`sT{=GVK1+yQaju#mqhO?;(xD@J8~hX9{Mp zAHQJfE`J>V>1PVnJ>WMr^PU-C>*&)cAb3{2;wdT`CiFjb>JGL)fdoR^bV1UsqBnZ% z#r%ccfPZCWK3%g>-(7{gV2xA!LRN*Yt3=Rxtu*H%JcK|HNqPcr5~A$$CLeQ0fON?8 zUdgd3tb&YlKWuIZUO;sh980rG(YzMtZ=G-*XB|fRz@`3}eLZ%m8dxZgL6YUa@Afoq zVvgU6{|O6}g=?`@EZ|Z~T4E~~4982_IRN(G$vx?;!W-*D2^)%A-T3gd?T_@Z)tY@% zol5%=+TN2`vA9H$DgXl~aR--F$gh{5@*vrO+NV4#q+Dho3^VBTcHj>_?LBOO6^wR5L|T9JKcP%*1EBPsuXcyIhUE1$F@ zd<~qqzy^5;0lkQ*6<&_6Zr1T?qHOrv9BaN$EltskiJ1h}&qicO*?8Uf&V%Vf7%3a+ z^?zJ`!8OAAr6vS%kx5JG0zZUm*rCKS!O^_-V1OWj_UjTGqws?5Y{Fz=pP#UXq=N5`vneoZmc9G6;e z1Z?rB+0@Dlb+iC*nbm4&@LoSTT>rH-{5W@q_$&Hx$YUGIiV?@T3-Sl`^|q1{ zKBl3eyuLUB2o;+*XN_&X{!iEXG|Ji;)pI;csG;YRFDBaM0g9!_Du0A8@E4JBK*LkV zA}|uRls>x-w*NjbvTWQYxC{=w^FXHQW%f*(5h*UcIA9+y!&#hZyY4^klH4ML&6{z5 z;^Q%!+x|p<_o0~BJ3{^cl>A(bQZ|e9natRp%9x9c5}9Rhd{v!%43F;phW_X9bk97J z?eCVC#9jB$h3nVvmo@mb*L!WrZ)&HD`n=b!oAhb6%pU`Yhn-kU%kTLQkKe}pg7B3( zwK~M-cP?d{70f|=y{yKChaLs6oI(V0P;u79TZEbB`p>U+acC)U`S-D_6HrcORz6!S z8twMIC9U>fB2m}^TE|>=(C6|~zR0ky@`%%IxNA$4?R9h7x=n|F8m?9>5`km7s%Sg4 zG~3e985RUN)Sc1GcfM`2F@XdR(6fQGH%DoH+}3FNq+} z@99eV(9Z|ovh&(i#1RcL|Ka|JT1d}_+!3HX>k4383rMY^X3O(=M|_}(pW?LP*H8eLWgF`i%uS*9pn$ zjs;jU**uC8ZcO{~Ih^8%_U3n>6!hjK^OicYMQC3JEe$d0ouejMBUZY+!6)Xb@Zfne zB-weZlSEICZgJYQIU}ZIJJY0S{c!y0FDIbuHrZBm`8tDUbC2U_z&^)pqsm5%AQP@l?mtG{dJ1zzOY-@_P&m!kkCWpQXhzQ_^qwn}UJ64gDSg$vmhw zhKD1-us)g4q~E|dp!LpX8eIHGz~>$I`MLrG15|{7_|ETqU4_Yvc{tksvu~5F`MJ=* zAdt;bg|No*(cBnn5=a0R--@${o-pboR5sb^gwcjpOBHm|QSmROaN=_po;x z83j>$o)kDZ%Ilaw?uq;=0(Y^`g8w=eGS*mJRyMm^?wF8dOT*K*$V=$L9{8wNzT?LC zGzO$wIh4_Hz^GAFduJL2jK_N00#|LtV?u%#AOBF78J{F;1PA0gN^Aq$*<;H-G2_r1 zk$kq?69cFs#<>bN;pj2t3jN-R8{3KtscVlvS~oLC?4~Ii&p`vr1RIE-WV0V!d{Tm! zFCQO&&cPEQV2EVm1%&n<@&y{n%S<&G?gjD3BD8sqw=9gTy-$3dw1?l9`vZb6_edYQ zePPU;^Zh(We`>O2E&K_6-p^sJ1FrptPZ2>LjJW-|Nxf5NQd~lCJ^`Oi0`Dq52*w?$ zT98rGo-T;B6KqQR5kbO zWi$)574g;PxC**`OA{%MP5DWmX!IUqhY<OFhO2Uhd-;pOLA(dlo}vEE*?F2KpGG&#zT#nL!%Y#SIxd43#aj!NSz~+QnzcK zVsh&>Fi_mWPxR4nP}25pyV9G+?FqYha1jhqv{X|V)%`?yI$X<^tqtu5KZEg|#-yH$ zI{A$5@Qth>-Oz)$n01Qap{E)iqS3!Wwhp~0+}sO3n{GJTZb2Rz4F85z6{YYV=jGH4(I zNvVh1#e3B~J?jJdSv}M11-U?akfNB^hzL0}%;UgGvC%lKoe!`#A-djRRtSe3Iw}GGd-WYy=>8gvs-`F6|dureKwp_?d@??vB_?&jC~AapvN&-NG_(Xk=LA70 zoN;Ga>r{shDHit2E0D0o&5T_c$^#}%BU{fVLD~WxAe~LR5Db%A;HgvxT3QhXnEI~+ z_k#{_1_6Ttmp84$oVKq9S&+G%fi}&YHkDG?r-K(azE36zn1R%`!UXR#!uJw&3WbbV9!)O zH-DZJHl`gn2xb&oBTh?H%CAK4q15`X{ii5X>oeYtBUc@y?KyE*yw&wYZ3Q@dcfXl{ z1OXa;>?gBEj2dr!3K5<0SXWs}^feU%;L9J8P9r~Erg9INoqUh_dhn8}Qox7d;77Z$ zJJ0QxvRqn$O57+;Um(KmlBJVuxpXgfyqc*p z`qer7_IwspA@sd1C9O6!#^HS0l~v0%IEXd+sQw3j==&L#5WS^F8kZrwJImbLa#NfG zDitg3tEwU~7L%&qEc(QouL#>{dhB1Vr*R(_w`;>GuXdPGBkr8ZR&c-}H!Zv|ipka8 z1|Gn-Ams!?;@P`h z(DYhh#XXFN&IJeE&NsF|y+r@2dBs1SUuL!HD8Z*F2W^*izOOxfbn&GJ_6dM6U|!l}&y6$Y$JU3&s~sx6*2d+&+bV&lgiPpIjm=kv z?g=_U>l3Z%Wc_LBo)QM7*e+#>kGKyei7VGk6bb8UtDI!ve1t^maf26_1#^YTJ}0n? zSMP3v@I-*x=^<--BbKYQpa%;K6k)V=A#I{{%fC4FuAnRHu!qkzmquI>A)^1JeGB~{ zOcnQj8;A}l(;!bdC4>+dExt(99T_%g=FKV-E#egW#)*M?-pc}H8$wYBqE+x!R0;?C zvOXfg`_oapqgBsPYcZoUN*nUB(qb0qyNAkt{OqyU$PYxa%MAIm2{Rp-j6vqlKvtCB z-kbbwUz!H1by!3!PP|H~^koqIj@h0I@`?#t`|Z6Q)xl>E6}$15oM_y?z%rT1Ii%PKAPmGF4^vipOqA%|??kNOG{biR z^N|%Ct!t6J9A06lxn>hCB=4YAR>DY+Z=-a-=<)1@E0%uEx#5s%Ffa3Au6r{}rcx2m zHzST@{|5j;obLFMh%^GrxOs@$oCz7z<3O zGzg_jb07eN@0$OtjJcmxba7Sy6nLAM?nw(b!Ul)+b>9K7&E=}^>tNf0YEgmGf0Vye z+aT7cc}0X`RHX%u6*TUGGZr`i47~~qPJ1=;bMGukP{7buFp=*HJG0U`5{4T{+F9b-x2caifJcIpwjSu&e zew#LL$bF6_VSJKW^GqJ-P&&c1V-}q;F)F;-Qb`c}^e=nR>3gVD-2a%eKJ+00tk7jJ zv>jwoxV$nY$GdF$J~ zbpn;J^;VxTdu`uIlUX-;SX$*sxxRuOge?YYgA~`7hcvuFtM1%HT=38ne53~%=*N+z zNjrPWTnL8eI*k&yguB1~$pJL*zWhlHecyiUn5QvLLV+4KuBQ| zKlPlOkHqKNt3EPnTmaVk-VbF$+3Og8Bj$c~2#quDRN)Qwd&r-GwM*KXs(Vq> z4E}GuV$YJ=1aU-6h0`WVgYnfH*YY6_8U){~@ainjN5>`moQ{b>x!lH`-=#Iifaig6 zbm9J^CvN6%$h(ky>O*rr*`wj)G5XA@a)=iNdpF>vI8gz3H#vV@C;OHRvyn6II%KI$ ze!<*gu~hqp0)`RUX4>{GYP+0%*Z4~+Rxxeh6225FIyGdXs6jN(uIP`b!4%td^}`aE zJ-oe-sfTXB`G1Ua0F$mjb1D|r%yDYf8}Yr=zVbv!&^A!Mz*la)G2Glk z5ubdPa*|r=5EFc*yPixN94e#AW?s|Fl_QzIUf^EZLg1JBX(mJ1aTCiYo$WXBob9#> zg&qeyHhnZlD1E50=A(E~m1#o4x-4e#W-~_o34LlF!J1gsGG_av@)d5a9Su2*qh65Y za{DtgzN&}YNFZ-KcnwtI+Ms+-8nQ&A`%`far4F-OX~_%CG|iUV;0*Scojg`uhJp(0Qx3 z{#yhKN=irbwqTnDWrC>@m&R*C=);J`!gl^;_F%a10xvgBbiyX`T5*7!Fi3l1n;-2S`Q78@EJOO9B}>i9RNbt&KzgjO?RD^y9zT zDyJ=GN2GoDLwXV{T`ZMjZF>H;(BM9!ZIY(AbqVuNir%_9t(>1<0#k{ws)t^$7j?z8 zwW}ecxk=wKb*)N7l+2ffs%X-lky+rx%pF0Un4vcz&ULQ6pzUc~Rr@&2NmY9b?nTxt zs{OS>`zW`D1U1i&9r_xW?S7^uOIj$I%m9FSBQC|nBOZ(sMTjHCXK9*E0t2Qxey#sJ zsJf15kO`D?m(Ud?;DDF<64Be^^Ar^t^Zh>eHDEWO5i*KCp#SqW(SfE$RGU#SX%`Mb zOCNQ4SVoT3dHJt41g4gi@_FD3H}7lY`x?CfaV|20rRCttR=ULl?fQd}MqgNAH3Pr& zJsXJHC(8qi6XdlQpMi>xXsI#4zSzWN6_etU5vURI3XhBupu!OQCiXp#(NnCX8c6Hj zUTDYB`j&fYJ|?M%RD71qb4yCEAGj#7h(tjh?hitI0>cQv3qNc>QlW92Y(loF>20?Z zc=CCKFnPSOMDV1YD^V9h2EqTpf7GZ~u$uhn>rcnNp`5FbMb(W&OhqaSvUF^>AqXX4w|gbD12y%$s5cH0cFT z{hpS^So|i>0h%y^WJf3Ln6&9iNE-xaK(GlA#h{ht`P5rQ0*oLH8}&+6>#1kqRIr(Jn+&ASfYBHhl9+}^fZVf6RxrHE#| zDe#0sHo2>9)|{uA<#N6A$Ni$+o`Wjr0^K~f;|MGPLut8p+oe8y7^?z;OuO8)zdAFiC5nI0w zx;k#OPq-7jihK)Rn!o@xetz#Wop!@`Jb8v~**!mq(>-=c9M?eG30IAGE)c#p92JYP zn4l1e=o}qj2oMV(_)kQVmnVjP{^8ux!3po>Bm!4G0`|7u7!pKSP-->NNZrXtVvx%j z^?pD09<;JMe>4&`-jJzEd#Uc5)AJ!EV}N4zhvsiV&K25J_C$U712Ypk|CG-_s*_>e zF$R6GKd!I%Oh8=*osy9#9TSimcwg|j%`^>^5dJ<~j-HzSD*o{gyo5+e$qXsgNGdRQ z#slsYYOs+5E)}V)ewNEhY;%b|cXKmBslms1G|nk~Lv>Nfj~L<7#h6m=SLryA2M50> z=+ounM|sWIzcB;6B~)h_Zh2O`&wG{n{si7{qBHQ&!j`*=cxo&UuL3=h3m#gfBSPHi z__9*pj@dOg< z?ps^sTeQ|gqBu73)crdBAD8KHkUuV$Sx9DcH=k_pwlYXIi&Zx==8|7HH(Xy}8G)4t zn~(KE$?4f~HON{NWNr2XqQ5J8MrQlMZJOm>fB-}_)HvmyJQ2$raApU6sCosp(d{NS zqtGIvUUcuG$Xqq|RsHb7)>^w;sJ|B&Lx$h*INtg%hs$|p#cotL8OLRf0!>fstAs$bspHaT%9PgYQ>T z8>WT;m4g&iI}UVn#gOd4$W8$9Gd%6lTozoSuND3W3m4N@$m}UA*J_-%xFSoAR*A=1 z@cOm_nEjvHHx(oT0s);<3~~~Uax89HUaLI3b_o-so8`gi{Q2r`mxI54NdintBUqp} z+ot3ZEsP4Yi$=LEw>xQWrcD-go^jpEu{4E%+1z~6k_s-8lr8MGDQ6Ug%4B9Ty~ z_BYmJy8c`DdT+AUrni{t$&|@*x3;uBt9RBV z$0z_Q2feFj7=4ZNs%uN1=1%dH+u+mv5tZLIZ0^TX>O=6FoT8*aa@x~l`UnJcP|zo$ z*7ipbb|?;)RmB1$xGR>7FJW~ukDEdLTo13v#>|V#f+-9TJ3dJllAmU-Lx*e z1E;@TRpN@iY)4esO}cGgr01qY10FC<8T#BBkF<};IU|CPk)sXKl~9u}UGrCmju0Rq z{!FBCGf_K^9GLFK$RwqUIAQI44zWAQtRzVD{&SvB*s#ERkFsaPK?lYg>n|PSx-5#c z$}q1`Ik4~0GUoc^fIKMX3jXUrGkAC(jVeZoOkKiRlntbaix%c|msDOs@!pTA+ZUeL zAoE29x#TJkYAYGnM){gXfp?ujp<#c9G;gB&k2#qoAyJpNBW!JB+ko3$OFFyB4|< zVg*QfJ_pZBbfKr#W=CM6BC=5!%9eBGvcs`M2jl<8uC;f9e$N>W-6P{OiH^Rh>5ubq zl*_Z+<6RN@w&eTFti{anQEftO`%fV8-0l{%p7(G*&ho@XI~h52ti_tS@hVqvQg zQx&vNA1H_lbhInK9Z^`EZZM*|aix4JY>g?Hgx&w7<9Gzhoc!wr9>fVH z?YY#}$#AP4=}>XuII5!qI-oizi3H6<=iDAzc=EckLNhZJzg2CRtqfIk^boI@=8nl< zg(e!~aAE)12cl5O%s-GvRKrl;v!N5Bf&jsQ!=_XkK^=wF0fvYtGgwzfZ4hylweCY& zq`$Uu7l|}_RSgD_KRcTXod<4_c#xyfM{B1_h@+Wf`T*LJK~pU4Dw?->oxhFKPivhO z-7hkM>CVY;ZD~t8P;;5VAIVcM{%llw?&B2yraUJ!2@4t8f)wLeag?_wa~@gdf9HJL za`eWgD-UzVs~Q<9xQ|4)gj)Yo^NeqGCSh9D%O_}~C1RaFde0m}39O>>yGw%j#O^TT z!Q#Vn<*QC}r&>je`4w0rL!i}H$i{`;CU;2FUI^Dx=)mE}?3drU$?tOeNHjzEx9IBz z>eC)YRlCAQU`yajB71_FHLj8~_4)D;ppuYU#Emr|+X4Ma-1B$KrwXta;H$ZqEyL?#)&1$AKoCH~uh_r0Dd*;zVQ2x8C3KfV)BZB1 zB!~y9yf7GyJ3yL3;q7}AWaF92`#IsTdG#_UVb+^>VU(Vrz)qyZ zahc=uTt%SyR(t`bez)!F^-9TwR>L@H&8;H8Lnm4wSq1RHRYWFrv1Q#lt(2D~!5D!x ztPhXB=%CArf@Y1G{B9rO);uAEI9lvi#2FJ2 zr}+zrqAfYSc+F^>0&g=XVpam^sv)9x_2^91FmJPFh_N)kQ|!3_0t=T&^G3?Mr1G$L z3Ed271BRasb9J5_a4mJ55Vt{fG}l?$YSMLl2}#Ith1|+I!|GR9c+H4^$e8Xj+?Jn* zvqMW^)*lO(_h}jzWUi-1-HUueD}z%4nM5qoV0)J zmC!LvLjj0TA&5elh5`YMVK5k_A&O#@rUICSDGFkk#W7G8xsJcegMqtK$!cgLA|+M7 zr6al2*n@hC+)Q-|GePq?HOR;U%n1dNA#TaJ*Vkh6j@x3m|9uonFQ09;Wqtd*%E~@{ zDEvPPl!PslB4l(sYp;Wg3vGPymdCQ$X`Hy z^jcpj_uSK$hW9<)Gy-lCr3uux!R7XBoWunhmnfDy;EogU6kdinHk#UqPV*%T3dS;K z{Maqc-(-Qb1gf7CzwB2nND5J-DIGy^aE%;SI=@U%&Uewj0PinEb)jN1q+bTMhWgL# zDN@zZb|3BG;o7kS0Y*NCNC`8arbSQbmgP8u=7Z+=ENp};Jv}mwX`$m=;?QL>+^f7G zoSmtI5cjwBjU4O|SJe)2FkB0V0ARrAru57|R4o>eQ zGHE#iSlygzWl83@TiSe*_sfJ;#be5Pcm(LYU%LKiZuVD&$)E3JQ(|TM;wq3cS6QfA z4B0PdkdsTFU#3uHY)19bo7o);@YQRI8rd+VBS3GfS<|pB&r6^*kioqb0%0+-VK0Ny zb)!HO+Q_%Szv(kS4-11>xf6K+efZn3Ox)ma$BS6vsOemrRV*IGuP%)N@DDS3BIs;( zf5Oc3L|P0R+zS5aJjuL)d~S|(j>#b~y01Cj>gS%b`Hg+Lgm#^M(MVr+*1~jJj<7B# zt&wzx2ZK(H*TI5x1j|jnp%^k`^Se1jj1B`wD|BT|5;GZxWrXR042x#WRBYPH-+U(*OgYr>D=dcW4T>3)z{h)H@vOQ}YEusl292jQ=K? zgtosEmX=Cu>OYUiK`*iFZC4vO1pDr}1E{GZU0LS<040o6vIVt`@i*2;jttO8@<4-) zDcWH-~+*NlZwm+GkHAj~}NVR0}S2~va${h=QhP}}M<~T&w%br2zu;L*Z zG3Msdp@3f9G3mg2J z>k3@f5N~#ZF}ug7H-i7ms7yNXR#5a6mrQ1J@!|GivsQ?2?k8{%jy$)?jh(nLD%!k#h2=Rq=ti9I{g zp(%^yIHn>|0Ze}MFo#dZ?IQ8&JSdN`aUV-Rt-*m3@3zvoE*}kOvmgh#t~eOUFmns{ zTTZ-rBFQFBp(-3kx%g2kIrRPn0l;2-Z7zCi)IC2)k2+5{Ltp|yNq@S%A=_=P+J=7;)hp$oXWwhx)rTXoJog z)KP#KFeau&jDg$E6aCHCX<{JhV7xs6D;-P|ue_AS1WFM9CYC^&ReuW9a0P3(`L`nY z`xS1ZA}T-V9{QX^cKc_lT4c8&$_WDU3Nap~Z15zH7U?(*+mf2%y@VMd1i*#V74FhA zg5T|_DUFS5;r0}l+W=@Yyoja0eX);LdgyX7ZP2VUb_{&^C2NJ~xG+M}Rgnt>No9$@ zO+I}3XPZ$}|HB&|XR4W!)f*k-Ns@)SJ9~$qU-KT}WOx{=5a{4oTY2stPRZS5#Hc%2 z_C18`yr*=<9FGVB2pSEV6o)jAzyLxd$XZVu>!(rGIT48R7fBYpMbPKE>^$6kw9+Ly zKGc$ha{Oomv+I;#??=p}A#cvV5MM@?%G#?U8yKTN9XVPT|5yzYLF75PzW)+s1sVsu zA=PU8M}qgbJO`m~Ld0VET}AKvAOr%a&0M>>P@^BB@5k2~Fa*sm1Y?5{)6~i_RTtY( zs~$wJI}Gem-6(Hcta>UorfW}udDgXNK8#vDDKi{I5BENh_LC4+2)d^k<+e`L8Hu$Y zc9*=6W9@$3i;ygEKfC(a#159tt)E#_VpnG#4LVS@r%zT4*N@+$xYM!WzbDt>ecMmR@(w`tYw zrE-r5U|QPUq+~C7*Gnsu&;W?uVQq#uFAV&^jq!bqdqWH@YGISO#)d)fQ$vYApURQv zW9DOz_*YZ@t*Y?|e0JNsJSaaZ8vjhUM{*hKQ4GP4_Ai6@&~vczkO+==cEL{NgwzJ_G)3Ot$$xw%^sf*DN22UbVhyTK zcW}Dkw*?20kHQM;t}s<)W@tJc7JgwS|C%Eg1EblWOT0en{$wlP@ow?$KmsGL(B$Ad zQe3}8Q*@=4-om*^lt$?ZC=7rAh@x<;0tJ4P=hVV{kq#SVXXjhKL^Bo3Y{`AO>-9)s zhX(vh;QvI~)M|eQirv)msevgKd_$FQvPH2ZkPmJx-wej6vQ?@77naHxfPz!p1{P zENzA&m2#7NUUR54q&e`m`2laG{S`zyWwt&XRp?DLQpIUdmpU`Itp3teWxKqT&|w%j zb0Ch#l9Vd{M+h6&Y3ProU4KbDy32CF7vv>r5y6`s5|hz8M~M(2^_-F!)%3ap+Jjho z@{p#a;uk=xImB2>EB8bbQi${$4=-bFT9xv(CB5%x&cFyD8NP9FOVJr49MyK`et3@7 zw0?B*%)q>g&_xDpIb<7t4 z0MF{M#sz^m>#J+Oie>IB#Z1oyi(!lKy0Cop0juK!I3`Js2nM%Z~9;_W#fye9}W) z=77tTO6zX`D_{j#7&>uK&`6HoMwA`QP+XDnC5hf+>ztMT-+~4-W48Q< zapv0z2Xq-`rpx`(q=pYaHD9)t-G|0|KwPjK1amB$L6umwlMo zHs0`v-35U64-}T4H&NsC5L`vcjDc0xK8JmWaN)U6PQy%JWW4&C)}q%;^!TqDPlm~# zxhk+u;k5EdTzpCA>G&R%?$@Tm{W_keb-InIF(&QR&jX1PD*nM{DSAMIF?So>hFXC7 zxw>%$j}!=t_TC5>369?vGh(5~P7mxL+aa)?q@}PqQ0{0ui8!nBWPZbbc(#qst7s%1 z@yCE5fYSq$TdD2CCAnJy*KRN_5NE|H8`6A(YPUVLuwLFCb%1=Rs3m_bRwISxW~b9G z+`C2C`@4%k2!*!SAA!PQRX;JmlH9liLnaL0obP!n$cRsfU`JIQ5K-6~C_4X& zGV+EId}Y&Y%b^LHo;5jGGU<9xmvvl@CkZnD2&`oo|JCWnQm8AGh=J45Xw$Z(rIv>r zr?FFwyIODdE#*Gz2g&a)925@|;+Eazp=0$mMgPu&OT7gO_0uj^C&f4|=!mO}0aU@@ zE#a#vnk^W3`t|5|Eg(M8CO+R!;LL1SUf*4iA&M0EU_M}9}OB{{~k`-Y*b_V zZ$K%4L%FiTDnYo7ayOU%D#mSwLkN5SCoPjXHB?*1B8%sXC#~u~f#g5D9iY}{oay^C zWLVe9oB7f&q9KRfue#u`=mC$my2w;qy@%((z<4<5d8cc{yFx;;vnutR2ZE88Oipu8 zPQP*`y^bd5JlAm*5Nnmi#*ry!4kqgpw2W@ZiVgk23pCAvG7#hI-u%NG#lPAL=N$gy z_G!!X>6RB%vZ*Jz%=z)Lm`rZJfe3s5Eg1Z)_Wrc}icKq?p>W2zUt(!3Rzk?46BP`+uC}hn=VdLk`K85{1%>&-XwC zK}~(jLTun*<{zvatmk$&Rd(@d&o`pze%AhYT$XTc1*PoIsUd%(3fmqNFBt_=rOTn* zhvwXn7gKJkDcfmi|3GeZSDQ$Td8r!t%2^x?IfqWTFsa5P^Ivh3-D zFnr5UIeuekp&nqNfNA z>wO(#mDc2rn454seQ2=$l=y>I)H-&=ip~9ETeHnS=rw;N>{RYyP&dCoxJN!jz4SCM zknAmJDJKXC*P;&9YdtOv-FAIIq^jCBPD6`6nczP zr)|{?=-vTiX?68A@8o(WEv{xn2}Nm+wp=3dtc;tK%ic1Ikm- zzoiY*#(en?Ft3VQgm1Z9c2xmTo_KP6{3>8L9eMT&i;Oa=F|Vq;0CK5cC{5`vBzJrS zkS_ZG$_Wb$aZKFn?#{B0EMR)qMWf-G{I(%i8s%)o>nDp}``U)5`9So65r7ud&+Ry; z6Q0V`lW6Nv2UgSv^llrDNLL_K{t_h+FohK6pX&Vel76?OMzFMPA$ZIC4qH#<_M=f| zcJN~Rdp*6AA#MEs4r*SV50Z8e{g{6UTFtc|5^&%c3du(jb{D?_xJSze9HgEp!>s;R z@zZaE+cKb8S2GjX#iLo*@1oLLaNR9SZ~PJE7BvpUS{>sm9?qOl6&Zw~KjOx#_q1A^ z)q)0G)KPam^rddHZj33(x>m}#i={SuT+wEOykw355=;k{mhfaa4t0E-)oMRFKO;QB zjbf&-6~SEa?7*duq9$nQNCiTq8MXlj;ygdmFZ$d~KYoU8k$)_f-shi(P4zSo<14$e)hp|7p)y?Qm38u2vAm5P-umB)}T^vvW5zhTi7q05y z0TEqJ-y#4aIc_hfD?O>401*{n0waIZEz+^0CxXVn07QJa0$j8;=BZ}*Tb+LKs;zVN z?CmSSK_CGUf1y~R5hlH@nxJK%w?<@nqCAJ2gw)TvlEk#Gdx>raM$xyBr2?CmOOqt~ z2WBnlp@AE}xGS<}5AfP;zl4Ec3X^Y#O_@?UFZOfYK${y;MQ)eTs#y0qsz%;JEXFA6 zNHJUKb2~Fcbpy6BA@Wq_{@b2DLZpU9mswIGyN^;u$Ps8=mk&1*5r8?qE#LY(f;??) z#}Yqo~5uT#W1*z>c3`)-z;Jy%F=F|kL$`)>)}R1KPo(%NreJq+bYgWCp$ zLkf~4AAtt*F&Y(yywHIF>^oHng$Ui16!@%9kq;sF42aMzqNVyyclqB&#pfhN>M)8M zY;GzZCSc>msYJ#ThI`zFGDtJboWJSBc-5Lb&|m;T1W%{r*Pu9K>v|O>fvxS3nkqo9 zg_^HiSF$0Rj8nFvWQ~}=@I-#hJdIrvqf`C?oQ!$YJ;l%V@kg{xT`v;=UO=J0Ll@BL zeC75(7*4$_929ZqBq_<(aYYx28pm{0k3Te!?^%RJZ6@gR_f93D`i)>dAjdv%!np^M zFUW1f;I@pv!b9WARQB{>SNi(CXefl{ejin;_X>V7uG)qt^_TWoq@UIN;>z<4&ep)4 z#Ws(tZ2ZHe$XR1ZLnR^8`F=p87rJ zTF$b)@BQ`eB9yt(;&0h*@(XeK_tX3JD#z9^Y=7BmqE#nt_j&*73w9V16RCYc(1NBx zQB(&5y+Z++_B#5K^o+G+XQxtuaTgc6@J+^a74(bINg8Hy2w}GcK}2mU3I1r z3jzdBIrpgiR{J=POGwU;FPTVfND%Gd@s8nIC?^(`00*#tL_0f-dIFl3wb~=!+snMat zD{n~l?&M1WUT;M1)K-R0dQ&Y-d^vyht20a2tK$38!R0E0S_a_;W&ayQtVM}VBDApg z?ILlPdB!%p>&d=s8gE#^24;%35`jpp+iAa-q-)O}IDOp9fXL-xXR?_2QFeJWG* zSCkefZ%H^!HmqjUb?5a#6F|4al=~eu-FZ##AdL_%w~rqC;Ch|lku(rzli~38=csCR z4!9g~F@dDJ+<7?>DH_stIY8edtdfats7+W!?=BE@g7O)Aw7*knRJx?`^vuRZzaCVR zL_Y(K?KDae+{kdL%Uqa02(i)9IuFa88zXy<%867pn@Sv19VLz5yWeKz!-WUZD^Z;{6F^A zSBO^o~D*KHc(! zfa@%?Yua7JId0_;(_;d3sfbX1yRr?II>?1IUT}`imHZak%)!Ae0Pv=NTTO!nFSBl_Y~G!J^y@Z7Zilt}O@r-YZl_@EUZo4k zyj!J7Ym5@Y=eQ3N-6)Uq2%Ap69Pd#>=lxt^Q0X|Z#KQ49%D#25#?$B0?cWwe0xT_7 z$~)sUNMrtpK7MWjoqeE>{$bPG?5Vi}g>{#BhAgr-sHq^0FQkVgB@mT``g8; z)v3+$7o)z^1`~L=#qLT`pPK=4kx>8v^AUXvr9%z(+vg8~Lw9FcsoujkjTBNX8%fZg z^u;!Z=?x{DKj4w~s@gTwg7Me0_7AUEdz(OlYf$#L_Z7|&z!v}kUF!-sW?!*BPx)DM zVFmLk*1QGFa@54@MuL+f=gz!51&h%W1HEu zR~>1%i6U_@FGMAMow-P?L+{8uCau6;eo=8e0S3noQDH+7Wr_3D00@ompL$a1jLl(ZIZb%0Z>RjP2_9RvJ1o=s zScnK}x-w)s@BdcNTxmur z(mC*or>vX3D&hM>V;Y$&>5**wFh1X}`>#D!YpBWIyWmV~_##=6fM0BZ71ksA7Ea$3IbKxxv4EcWOQ)sl%^@Bhr1ds$*9-?GwfW>hY~AdFjPl=+Il)cT zzHt5{8!(@H7?5K@Q{hYXi_P+^{W(DL8?-NXGA@__#pKmMEOiutyEx%q{KG`9afr*8 z)tW12Y&0>Kd|}cPI}{_Seb+Z*_6Y)uS)>PEOtp*xKHC{`U)|pzZs9xZp*E6*ghPWu zH{Q&3Nxr1I)TJ!) z@Nx!?0ARqV<_PNr(C7=5J>wC>X-$Jkjy6D)y#n%lZn{>_f0C=0pK(WAeNcQciTU7R zW3F0l72e%K0wLLWSW8YK=kCnEY;4L-s_vM)isiBI#E*zE{!?A<4|U&8UFn60?TVG& z_}+cAQX#S9wQI6y2!{4<`;fK$^2s^5mL^R7Dh}po&yNjHOTR)gPUKBB6%I;Cxb>Be z{Hy!^>hU+O&(=8e<(`K^&C^CUG$&k?e<{S#lRC>-d(>PR==mH9kz|6Pr#@XU@5sPq zLOXU|C8upRLF({zz@i{lTCZ4ZCqOOmIy?P_|ye5ItlEiC;prct^la0GPdKQw07+~lemzKS{-IO&2*BC?mzLvo0O+Q3|8YgfZN2RRsym= zB8I|Ze7vC*K8(+!9l~2++vVME_%J6iRe5d))sjwG)}oVROHG*v+unv6%Q^N}l#3=~ zQFfFA_)qJ}xrS~(ZP!67x#^#u(Ku+y`vSixyX@R_IRr1=dTl4w`!tV33Zs)qYaLgb z_|(a2f@xn5^{r9YD~Ro8_{PNKWOA9{AqWHl5P(1-2tr+?*oVPSC;*6?xnMqD73PgN z+zIKYr{S!d0S`1F0EnlZI0%d~HSPJpK-XW>2(4E(eiwqLqb+AyVCjq8=ry9xc368~ z)-S|EUWPuKXRvS~Mf})O&<c2kW_1sM_S2`u_v9a+9QnJGU`8LNc^%$pd-@R5;ywtnsLebs zQVp*soUCsuO)Z0^pNXD)B6|(?Xfq%OK|NDL_w)pTgM}ZR{Hpr$Q@bEER4Is`LpbT# zw86qGpfrug*}mkl!QgyhQ|w-$n++acEDuwGxCuzoKB8F6K?ByLkXvphy=0~xJ}$A* zTNHx@q$yu^=fZYHQbAA4sTa|9M9;` z`>DP*qeHIpz5Km%pc_Waf@7#FnjDhqH_GXH+02rYy#1j4uTb5?PqS7&+~DM8$p%)V zyRZev0A7X2rE<)6lsBoK%*)#6I%cvOYL z?8xB!0BJ&Tc9O3jLH<|2`#f#;NZ~w!6ZQ6L|9D1N#t4STPWgh8MmqA{OY{8dEo4_5 zr(^r`)}Y45J_HaoXG91fdnE6Z6B*kNvplAq81MB8_-34V#GHe0MqdHOXorW?D!wo0 zf6zISwUc)Gtq&^N)iD*;exLuS*QV%Jf5x^e7Lx9Zs*GPhEWy}L-}5AAwysu+Ex?a2 zxm5%j1tA*oIS3-0_Ai|nGKrD`4xTiRN2E1BSUaOnE8muzv3;M*7ghBEJZOqL0`Du< z5N~$_KRZErsD9{Wu`)bwIiDqh+%)R(rVbeL#S*Ler;)XF7_SF;oV`1sexswNzGNO( z_{hmTJze&!79xsCrf(<|diqiS+m^lF>`npgb zbM}FrD>6^-dfs<8nuD$)gKlqu3!O0BC45gA<8-l3Jb!~`!?9&-SLrD>~yX#Y9mnmlZ` z8_lBN5OtyRNSAcu{E(}W2p}fZ2Uu^~vRoDJ=KwB`yA;**H2%$W}Z}oUF`=($3V@AJTuFUQy$Qd6uH!TiaBhS~8 zj=GIHibTy}-nXc<0ej|uh;ij`MlUcIMHxIkBeE-!pVLhd_2CXerR285HF&^nqK5|R zIiC+2xNTLy;n6jcIP>ct^={S+0bphKbNTqT9k+*`oZ71>sudmQ3@cC86~B1h5eAr2 z-*r6W3$j<+n87*6vYM$Vm2OjhjM6Dg-rQpyr@Jl!qm+Rfl}e+YNfDs1fZG2$O%9(A&u4uK>S3NqcUAMTIcv5{GoI79&LL`0j%NYEM+U+MLcI4-PWaf3H zd1a%x+z^g$qy3p5-;evjtqralDMm_QH>&*G0)x4Ym~SU!61so>@Wwgx?&m(2B*<(R zMzsisUpN?=FNO-+IKDQoN^n+}Z0}$83^FJg+TtTny3?wmQu%mjo%;DW zCyUsQdrl1gJ<0VyUtFOR3)@$@NB+MT=;m4X@~FI^tAQu`m0p*k9|Z~Sk;tw}=va-z zGJlKo@ASx5dE9Rf>?ew;w=*VAh?mql)e_h`6!go0Cm;X3IVNg za;D_)XzSo-;;evU1-4-G#d*O}U`hZ$>wc#aiH<3Gfi2FKh>Kd9mLk%f)j$Sw)H`-> zD*Rv*W#~PmDFt<%y+^UORhwHR_W7Ac4mc{+r;56Wq=Lm2+dR^fr&;VwMzO$rkXh!+ z6DbRbrY&k!1!U7G0mz|_a=ND)A5*94s5eOR@+u0PQJo*Ois@__*X$Hw07l&S=CwBU z{`O=(hSfgcqQG4!WnkYC_L&;$_#SM(zDJsC+W?V>codf|Mh#gquM&deWss<|atovW zmq~(M3YJ6M$Inz5o3?Bjf{?Yiz%u-TXpjYfSe-Z!)DXkW0DfKcO}~ShF2dU_lF-NB8Z-H;%J&TUYAx*h zEx;HS1?m+gGIn8M`KVft?j4Cw2&)Y9gJ1#Q03-Ul!s=D^ug! z*U2|Ji8$(;X0`I-KBgmDOE8}3+pT@>oxZ!mxGO11RTQG%5*}R^Laes$Zj#n5c6-^- zHo}?VNa#Sy_uG?p=k>CSA$V_Wb5WKb@VpfE#li>=hn_}@Q15K=9|v!@MtmZpRGK?6 zg5%GS;EFdL|8ti`s|*eD)3wfuwzi~~*pd6dXGrd~QcQ?42t=&W9Wg-s8^VDHff(9f z_$E2Y*}w|(v8YFWmmjd7kbFg2j)(xz(y)X=+;V=%OW1%mW=-BUcBDyRxH<5zkM zRKn#p8vpW#cH7cRns!0j9O?W>9H)8_L_DDp6PKw}mE~F*OQakbLIF*P>)I3NyLrZ6 z>0}ZIaSO^q4Q?46Zw5aNE*pXHMMlh%0l5xqI5nsx5#%pEryg42!>0|A1?zC`G`Osn z5nFT239WpJ-{JiZW^2dL2r2CHP#~*>-o?mL)9ug4MT&tXQY9(B@R@p!HI(CtB8*pS zHVtDhnk-F#+1}D{3qZC%9=`?*4r~*r_v_s)O`jrSR})_n6mj!NbTPl~g%q1KYp~8` zhlKIDZ(IcSReqn!1han|wB?@J?g{YasKcF%&jzAfJ0ckC)ad}T56>kIHokwm;xx%W1Mac0 z`yLUB6&Vg9q<33kc0ncp#{jF#2R=p1kdeCd!+;;<+&S&De^a^I8`{xK^=;Y~{*vZ= zw*5bfTbAG}5Qxe9|Ec5+$6>mN3WN%12Cm9Rx09ObqCd4&CEPyow$gtNLD`a|%9&|G zw>)XlB|Wk7lD$R77sxux2SkR+sBzEjkC~b37T)ei@JP%n|27H;`nL&@{h(UL!nyO5 zs>>KE;AC2Nzo^L(2}e`2S@Gz{XGvRtl>e#kxOHp#IQalSixmQ8LNE-$_iOiKPXW-N z06-ndOHDgdh-vAqYYc31r0vrBsh;`l5CaKTB7|wm2IZ8R9ZhUf=-{hjl{P zM{dOc2#V%>9rn58RJRQoeS;2CoNH|F%Z9Vnag6N2k~_d;I-gw!t1U*Db zy&pa^YdLJH_`AvKo;=xqS1ixV04C(OuF}M1wj^S=_l5-Q-<5IsN@CE%Z9)zXIcksV z(&ctN91o0bP*l%4JTMo8_1~Y@H}N@1S+CizV_WomLzgb=f`4zcfL8sF#+jL%NbnAW z7>CIO@(#``$-HxFCX8Rn#a%wswymX`v(pSNS3r(+&&S*4@nPQn`>)F#LfaLiX9NHu zGD0B4L=)w9OCy8y65@5Pnan@{i1jSG{nu09XjTa_r>G96Q_J#c)6qb3Bl($_ceeIl zTB4Qzr23EhOk4s_4`UPakd9tfbCE_MCbXt{;v0oPm0#P8#*pd?({^ICt8jsWWgDlP>0*9EZWl^_`7`B97Rx0 zB72lQZ?X|foXob=3~wq{O;BBZm+R|;J3V{TRJSk2r zHNMoo%0wwFX5IdKp_lt}P~sKI74P%>HTBR)^>~tbqvIalSSnWkeOa)nOltJ?1y05Y zt{(?sM!^Z9NVxD#n-p>uufBWG0CNL>o7AjF!y0GWmc`Eejbx%5N)FNZ3A^-bgBF7A z>>s7IM`8>`jUQq$M{8rwhh3gi3tJ!RYkTr41Bv*;+Z|q8`aXM$3xJRAWw*u%tQa~# z)y8n*q79g*T(sb^Q#7lPt#~wbrTf$TJv7pWpt{t}Pcm*$=Ay~Ufp0Htt#}Tis(Xpq z#Ruo>fFOWo%<1e=pGn94Q#1epE)sm}xO(cwRohb>0@9C7LDrmvYEzfz(?Sj3$aJzP zkGoGBRKVuIfonjew3F}UZ~>|%y;CVA^Ycq4Bc$%i1dCKlTtf%LmYF!7zytjJHo>`?PsV$GdY2==st?J{dPc%B)`hEBJ3#OfKKAY zX0yye;%0efe>TNH@e`eZN8V$G&r-{j=Paw&i?xc}+dox9Sfxy~RcJ%;txtPJRIe9t ze!QKiHrc~>AEiAHv}q{_mH&v|1uC-J?q(de1H9J^q^4YB-bym+N8Kf?gvSqENAZ$v zizy}MXngYFzFGTr+LdF^Fx#@&HngHe-wC)$`ojPGm#Mj_Ip83?H%{FJ?I8qc*(;eu%{Oz zr9ZpLlU@uBD(ihc|I~@`>)>wShc|W(@ID1<{P_l&4RolfemLqt`KK3%kI$Gc*$@Wr z9}=3=m2ms<3YPWSWO=X|f{cR%6Of*dekiXOvrTp=fBA~GKL3|0y$a=%p3hfwmTtot z%IBwD=W^n%YCoGj7-&=CDEzJ5ImCw^t=WR=whIHadu4BpV^wq@?Vp7eZK*` zQn&qjB(o3qao-;1@@UTHwZ#55ArJa$U(ml36VBdVS~J=0QR@3>T;)mC^V>c*`qNv= zhN!0U(hM?!OhSnYH}p@R!qQ^!z@i0`*+zX!uU`zz}=B_}`uOQ!Z8t z<*HE|1+7{Vup8uq>G=jk{}-YbZ=OEYOJPgLboKN2YBj*xmI*>8gH>$#(Lz)v#(ChyUZ z2tVlnL^^(Vsow4dr$v9@>6r1+3BDEc*m>D32PgW2C62~-ClbUFx(ytqi%B*DBGk(} zj@?z{=$F`}E01N%xbqs5X{ovjkEi2%Az}aP%kIY(*T*E zH?`uB>di(RHa!a{o(R13)LHvPh{$=X2mqu#w+A`T46u68A%AW0muLZWhfVr1wCcGO z80e#hES=8?ISq4=nw>qz;?krahSIonEFTX%$(_A^P&l>RebK!=*Vah+qMzHq<-_|z z0Yor37P5x8iQHoXW`j)sk;Buw=wBiQ&P{%WwMHY}2s&@ju#9BDaKeNk?u&^pk^H4|H*r;$z{@c4ap4}qdPm^-NLjz!kfIHoZWMVS zBW>==r4Pcy9?^aQLI5B^x7Lj|C$RQSzDwx|Uu3@M#b!hoE`O+nD24UIex^0+4MG!_ z+wrt!;Q<&|e*OhO00%0BJ&p~%_m)SI0o?pl`mMW`AhQoh>su@0R&LpOLG@N} z%BIZaZYtFfkeKpswW-hYN-VPr0wA5R`3pEO+W$RPb(AFM zADiZ5l;QIybkarGz6iF@W~-y7nA&qq_4XV_VcTJd!Q$@2!9`|KTuxV$s;5Tc+zegp ziE4~D_1V-*(;kKBBY<=NT8XWu90RS7Kur~i=^PqJW>xzBv2VKK$+IQ;3tUJlL4NRvY+3ra4x~jILLa(L6zuoKfGESh zO4E^96|-l(yuMa#c?oPaT7XvS;+}IJ@j2rOs%Z9m4`m}VKbe2+23#J+v=UK>hoTEy z$$``~O^40{F`F)y&#Dys`Z{pnyoxzY@A_T^>3;58mwvt$gX6Fjj~*XkTLss?r%@a; zdo$TTf$74WfuCt*KwfTrQYhu!)KjJzJ?qhxt;RfyDzs}m?fCESP$;`JWA)c#k}KBE z%aS+mxwrl@cc&{jox2N6GVzS^J{jx!@MsyAF^2~>f6UHdz@K?-1?83`p9+iB*>kgf z9UM$sTn!6wLLN!`A{(tO*UA7tLYq{!o%Lfq1ltqug2vsQy6Hef2*CvU^F=055+I2G zg+oO8JR4$?oOCIeuGM4gi`VtKmFQ6*2o9J==Qdtg7yCMzIib%Pb$*n+Zq|GMw^Z?= zZRAT=x&F%MWF&6%tWV+h$OJbdX`g@fcRfu)BYKzGt;($~ge^wuw#umJ`##5lsmefL z&-<&vOjmMA@ywEu)ND=u_TQQnbP;V448AhI z#hU;e{(+OxY^~PNQrO=a?yx1Y?)jQEOW)8v(cO6Ks=?#{s2%qIlrJ?-K4jU#Cz^Z9 zwj5JWkC9N;+9{5xM+Ksl3U|i0<3rGp<&&<0C#1N^cZS}cKg5f*Y}&Z zJ$IbF3q!Ku@1Q!3GV=^*)45ydtL+Wg(EaCOCRDtv+^Dt5+??UyYe(4kF=gcMDwdqG zL+rIy!rkGG6%Szm&?r^*$6<-~bu?b{E@!vtyEtMGo&k1p?7ru|ORo$7!GY94v$RS( zCvg=*E%jsQ+uCIT6-&H{bu0a;FWj-v5)A%#=1LD&Go!F_oP`49IG=}$z&urR4?zzf zX(ttWi%eU%fbYV|`a}6{9Xip3t2}&{v^-fB^KGCIAOTMU_KS=(2PK8cqF?<#g`{F0 zbRpw<9r7LJbN3LMLzp)LegfDY<9ZHQGu?cvm&iR|xf(yI&R=2!(H)K&-oG#7C;o4X zz?SWr*699^j2zuk6qc%Rxl&5Q1!I@KRF=GG)My^`?9eKYFDGS=#?X`95GmW1eKsEk zuHTP;L)M3-hQ^^wbUOm8?tXHY>xN1fcJBg*95Qs{4(I^{4@ueHRYU;j#Tc2Y6I=DD z6La0S{PFaDLD>EJKDfO-lV^uZ-1Z5X5C$(LAnMo-uwEBFSzp7=U>wLS^LR_q9uC&X zpidXs1QhRFtO3^Dd{>xmD0+9PWc@0h#MEKm)vQD}o7)}lSI_)cvW>HI4$oURCIHja z4{!*3071otDZoK5)9)*O0suCixD)_FTm%T12zGKlMS1?r6^YHFAI}TJlJBHjvfHJ# z)v)*76~2M&G)dwOaS0QMyZ0STuO<9Gm_9`_#$ltb<$ia*c^GgN(P~U6$&cchnB)ghvH2fB}I2(e+x4sqXxA>$4#h;;Mm0hmqg)Ao!VlkgjGAuB7SqR z&09Bj<-hd%23@9L=wtb&*QDCf4fO_>CDIFK3Tr}(O zd&G*sV5)uo;$-pJIdCugY)jSP9wRDB)dXG;{>&oaniW<&5#4EMzk=KTe*jhM+g`tw z8o{PI_MhMD_^ta&ggaky|ED>hc?bP=j3=YYzV<^)7hH5Sa8QjV6Q~KeZ{fYwv)DIN zpR-+gYREJ$#}>zhLG)|t$v}T|@MS6L-vXUJYad(!0b0$4cnpNpbJPud&rXoJ z4mQ~j&v~`7&!W+(kDXfWp^!QW-Mikn1%KlgXD z@L@euKmb}sU47@|M72v5f%rOzW1vwFvf+=9q;=PS|A}M6_2p3v!)QTWK(eM}q=a#| z*P}S3oWpAABu>+3@Jt3u?Ip?dSp{KP05D)gE2O{g%VvwV8}Lmy`ht=&0t$|d#xv()jv>Y@$GV!^2p4uoc`pI3S>dY<&O z_V@$)3cG#s2$ew?o6hUe(4jB@0l4Ans#Gu*pn@;vx7nFLCq|kH)d8{=$5Gi}+u`kw7-#UVJMf2ASq!HIG4lY7amV#R>nLdc zLPRgu`{<{q;EL%l*GTJ-1NVz$M-q>OKstc_OSCTe=n^%o2lJh3Offnwo!;GfyGpP% z9jrT<@@{Jz{x#4Sa1??e9*)KVQZJl69zS)6!z={JID?h(D)qMlz=@{rlo~0>|^iLqy5n&^YV*{Wa=o_orwuQwjRfYN=RcLVYMl+6V80H z>%#Qy(;5%hsWK{qz$c@m>rDFcEEKf*N??ppABL<83?fH?iwe z;daEIwm`*`SI0~hg}os`9h`o`f|1A824n6s8jk_nS9A7U@##j`{W2j6WIQkln0XvCqR& zr}Y6Fr7g~7xzx9dLMd8 zG6{ZCeI_d6aS9Z^yVYpy|0glv(ufbaEC|DR@9zdIc8LCGDT|`HsO+`=@AugA3^=?& zJfN}c7qpWA{+mC^F@RbqK}8*tlTG^kOIyf#sReIp@~DwiZ(o5h`5U)F-#;E(6?-eX zOxYF*`%M0kuqWh0nFNn?jI*WDGQBn!4<9_zQCX~@h0q6;HBNTgcfLio-_Kw0_#8;p z{Hn`dI=H-wIrt5$6pwjvZ+?Xy0$rGBnASfH^qdDE7a)K*OT1)E^zBC3D@)BO>Cqms zAq-mu4-&Z8XJ7V`Gv3BvXJ0Kc78d`N=E0!IDKZF=plhf=Fc76wdH}*e8F1SNMn+6A ztA5C?>ob&|r&!Z2K$)0(0p8mP>;Ej|aBQD{Q9jAE{9sH_*1}(a0V9{$nt8rn;y5EZ zmdN1w(GWojpKuP5UZ`?&!+A+_uVy^sF`L*~Mzi%A;sx#eSvdC<7ANa@e=WWpD83&e zE~O`9^1A1J;Iz)CM{7@P*2DP(j$(}s4XTGS|VANk4S^LyyJWvQFX@b+hPj6bImLd-`l9;arn+q1yi=$M zgBkA2cVe>WkGr-Q`%?Z|AvW~U17@MMr96}=550-?Pr6&>5rP6vkK|IeQ4Ol;?~1|k zmVSa)vf2LmAA_wa8`x8U9}SvRU<8QH8`Bdn?sX^DI!6)mskn@;-}~arG>EMWLC9pK zdPFNFl&MoIuwZN|JeQ}bBGxxmTV@s>hl#H|z=7!f z^J+~RhSFH*sOX@Kxi;R64|=HKcV0V@d~gI14V%hI_Nj^TbjHk}N3?lo4tHsH_&dA^ z=4UiiGtB>L`*5}yp&d@EQ~MaA=FVK|2NC*KGxaFEP&axeekBtJycKoUm$_MFbZXo5 z!>W+yNr(bK4NAzsQ~{G20vkH9sz|eKk=>(QPMmVy1|tt4kj>T+2xS(6amQ^g;)hvg zqo1Fl9CDi5%j+tIZ^lcq^CG83Nk0y$rw&^>E*&KsU;0ow=etRx)kD<#Y10QpX30fl z;&wVr?Q}kxiqKokQ%M?cIB>d_Fzk{hDWT-myi9q1B*%{f>*OJY=8=};{fHuXB7h*= z&X;IQyw{kFkLqDBf587Zt9fQ0zBp5cq0e*nKCL~pK^$6U8(ip#1!1dMlrQZk=Uf zJlv->FK>LW&eO!u`$;f+S()wqEUB2$Q?xb*d&cWqzHC1zSL}7M08R)%2q;z4JHTbp zlT-WK4H+R?b6A!;H)q9bG5Z>m?!W|$d)FghFt=(uM7n@pJpsC;;^hDxhH`tU%YrOZ zCjkIJ2x24*1K!7cTg`H8e>9@^`GPmS!%NBhZs+l27p8a3TOj=}!e6cQc4b;SyE1j_ zSZ`=XB6cDtd22yle0WU3pmq>&Z5CRmghdt7RiaeonW5`)zimhW&3chB@q`AH-?l+O zO|1iWgJTpGt8rhmCJ3n-bz4qQ#C8MI&gZ8vy#>Xshr_Kq%L~wkegJ|4utxX%rs9e3 z<+M{w67$JY6)p7S>AzYFLmb8;Zb7E`YkpU^IR=p-Y)OJ-waQqaU7Q(leK5dDH{jkp zlULcoT*ui2SrJYb7rKpm!(zKy;mkVcO!KJ@qp$NYcqHs`-^pA-oqa1Kb%n znd$zj>vb#-BcZ)r(L?mIz2=mCH-adXHGv498j1Cya#{AcEAh7$KGD*zbZLTCYczH0 z9#)qak)PbpSk1hp{@z(Y<#iOa%gw&$IV9eru@;kRpyLGEo%a+QEIo=~MCnA^O<$QK zd8rFtC1^FgKy4D> z=j`!7SY}!_g;~mhKYF|3-DMWR05kU?DGEb!PKW7!H#s|8oi_Qa%yMNqfY<3hsymWK zQ}%$%L7E)o86~CcGig<#L#$$5`c!pKp=A+Ht5Z zTa6*y#c5=S=P>+XB(TkNJ0(>5IhR-}$%Bz2dt5*S2k0`JmJ>NH>r#smQ2VWr+zk9( z0Pbu@L@co^w)VDj{_8Ov^_zF#6 z`}}HmXdt2mJQ`mK01QP^n|ewL>v8i%lbUV1za^=P2X8dgy~w9?*P454&o3NX3>uHq znKH7lgZ?~A2qZ6MDBd-V53}+^17pV$-_!6VX>WMK-H<+d^$sDv^1>uY{*%_iClM<; zfiBcn${49!S4UB<|GeqPYUhu8Y9R5{UL<6tlUJcwof^&`pt04)SN)^4V+;g?Sa) zNWd?nkebIlp&?AFQDq#N$E8G;RH~1YuX1qca3EHenGE`z@<{pYCPmjtGF@m4rKxpd zQv-P0174*2%PaRO{Fm)ZZ8JK&X_Tcug*wU7zBL~ova%%;MNo)1{;r6jgL8*Ao06-2#hzPVa(}7r zylfit6>u>b^`;|Eee(SO=m!?(Z5Gn299X3l>m2NXjBI{o-crb&ghUyf4Bb2;2QWc> ztlAaXWfyUOTcSYI{a(qwqHB8TapWeM=&-TYR+lnfVzZ4*VYe(_@XAKvxS94AC6K&$i zwnJ`uKEGE#T5tvv?OC~i5Fi_UTDPb^;?$f3SxR>F#NwT_TdvEVKq32gti_b*1Flx$ z&EwS@qjvjFm=3KiB)!7<5DNuy4q}iFZu{e)Ih4DnPYLM)#VH)@B|Fk}x7xmuKi}po z==cJZ*>2g{)f3&6A(@T0d{-|{l6P&(e#$K0g15NH?HF8g16o1^OMs?H)wg}HlQ)0`@k1r@0gbC&)nKf0U(XeFU zsSM#8*<4!X&kgJpQMDBi3-^p;QiaEDv{WL}f{VhvmzW*F>xGL}94NN@0i%LSI`=dS(f&+Z?#R2CicHvx0X>+K+{c;tE zh18*=rm)b3()=PB?D2iO;cii>n~3+>JleMu#{en$rIlZeGntBUH>oI!*${J4IFGrP zun;n#CXs8%BjU0C+To4R?AO?HM^0yF1P~EU1rPFbBcb$s zo8g&wp0@w~lzY&hta#F?A+^<~fljibj;r1g1-KxE5evW4<(%DT7OBkBLglV#zp-!8 z^=QNz@lDwkYx{84SDf3I8SWvMs)Kg>6b9y^ds}H^M#2G$^HaSN&DV=4W~4@se_F2SpT&w-w^mdNwvA@%zL)Eo{D@w;1I9O5BOL7 zz1;sx2J~^>d+)jGW-eW~MxX5Q*ZwXAS?X7nApweh;>8=e!2|?tPiB=oC+@(Fb@sQK z*bE{ix8Fls56;+%eblFyzk8`bpY9qEI0TbsBXL}CId&8JRQT&Xv*j!|VCxm(d&6V* z>A_2uGuTGh0w9GAcqXh`%hQx)rtc2zZ*v3a;$~3`t38P~VGuGXV;BD`6Pj@I!+R;%P+(K@CX;n z$~(^Jbf~M-O1%gmVwF-v&*3(@vEI+1c|_0z1d4wvIvbUo_QOO}g?HHd6 z&GLXCfhLRj(vZ2fJ;~cTWr5(ZX#_#5bA)HgG&L={+-rA>@=AMtvb~Kn zx3lmTKwRQ4Rsq?=~sL`|Bl*&OPaR{3d(sSPPTZe*Gl$ zW47gdXcw`4@X@!!K#P~lZH3R*Ci+C{LoC7FMz63gZ#4^ zLE}NmxUMwOu!C&7iB9+OrjXEo*jll~(&Fsqw?$b``iqYC2QDB$JxTcf+v_i!1cDK~ z0uScmxw?K-r&{J33I@dX$V3;{CBIUS3AV;3K>MdkTDeT&seD`4fnc{m4_y!u5daEa zZ84i|aG&aB$UH?Tr2q=$ap*n$acS7Dw_eXNK)N)iYE<-(DcGTjv9lOGa{rZu&ebol zSlZ~GIy+e04fgZrV59Vs^0Uzw4=Vq1^<#hE@_np=wY=;v*R8HTuuMDw@_<$^e!r9+ z(1;MK3)g#gr%QW=gjCnHsl8GFO(2$-ZUaAk%SyAol{(jrgr2L*=)h&Rxv$8D6&%(| z|GEeWooi3aEp@8;Z&&s#x)Km4`2G3MgC!S4llX*?9gneR^md->LlcME`5+AdhwWEzeip z#aN|ez!N>U4sOWk--#T2_noLnu)#>Hr(bDF;%sjCrJVw!TdL;&N(W7k4b8yKQ}7VE zsInfk*ZM7jj+z9I-k`kdcL`7(I(zfdALoy$ZiwTmW{#D8Fc(q$hktznlN$&=++bb= zN&O4@&Dc4FYQNuln<{9>yA5SEf>323f&pv5T`7b7c(;EZ%{w7v(UBe#M?(Gki%l=b zw|}LJc~Sisz}MmLH&wuOE%v#fFt#HdVR;ZyW`Y){SieE?$Ja*I<4IRGF->-r8!T$2VkFyN?}V(90aj( ztNVaBBceKh(hTa~oX)D>=wv#hd^vIPlE`Hz-6S}xuSdG$TDiC)h4lbOK)Ap55z5Im zo~~(>!seS>k2E3>0w7}p)#6_ie5~#D{d?VT*pnSeq<2 znP}i2*YayW6uFb*0=eG^*L6W@dKz5gCvI&AouT8wKOF9#uWq%+uVR$ofRr0&n=ahk zj_xQKH%Tl#sq3bx_Abh5mbn1QKw-ua)s9k!gL}Q{)}A2HUig`rQnavcZ+i|u9&l{& zgC0m3R_Zgli>n8&r`HW%Zk?X=0e~b9j>*_j$~|T$@zVguds!}KOv^H7RROCbo1p<< z2Ia^b;Gp9{vvOnDKWZ4}ikA<0B+Vp@K|%E%&;BKZui@<8C4ozd{EB2edCU%`kw=M8 zO`D!eA3z%mOj5>9Q;6WVoE<6A%FtuyYwC$nS&WH7qgb_rm~xL@x>Ufa*VST|F3fl$ zqPet(n?&qeoes<&R=?$KsbAzjsG-!hO1%od`kwI=c4E~bJ=O!n+)#{a8W`Y+( zZdhGCM~9%_pn>BJq?Y#O*rR)~``?>IvJzetzf8A1*+46)Ctcg)eQhhx$PA~#-C7}; za+`x-M9x#uee|reY|z&aKo~WE!vt%}`D1OW)(ts(Wby=ydiEm-k=3+cZ~(3V7AE9n zs5~2G3Y-sGu6fZ_1_xn}a45l{Vmgk*jU36cSJL>~Sk>$T6zs6#t6RsRv?Nkf{)D_J znLlR(yibQ{*m=Bd(tHquM#E^o&ij`dJX|~+B;(NN_Xe@HqXwaKxaFNigBg3GaoUP* zXUV^<&>}y@{TXwOXRKZsxQ2mt#&Fbu(Z6&wmFB);w;bzO(W=U>DcLtAb6u`)+p#k& z1VL{6KcA!Cp3a8_6sGy}l();ML(C+M{UyL-@HkYFmYFeYB8)7#+nz<#6wrAbQb0@h z8&wBGuIW>^EqKxsxMMM$8U~IVxP()Xi4PSpx+Vd0#0VJFxxWsdp}AQY;D7`{S7vw3SII~0kO)&dl+ zHZVUrlJXtHI@|UHTO25FsDfk^;x`{+;jjX|D-cwv$u;tfPveZxxtB@n@v}AYjS%od z&}sGDTkIa)({5G(Y|mK(n2oPeX;Hq)o+;(Us{`EaC~#09u8j{G(~dVz+(EfgZgaGt zUt|Abgx*BC%2f?#WP$^k`rry%_o7p3vcXg#M4`Fk4si6So$~L>i%3K(@aChw*q3rk zgTf<{KU~xBAv40H;`RnIDB8A}GUSsjrt}ug;Q!A6f@XL%2Eie2M|(v4)vKbDDo*m3 z$(VFoNs#KVl+dB3cGCqq(AC=3qm&SBiJ3z>|2Bf9`6EP=a!pR<3n+eoU>a{YZp1g& zy;^Z`4>Fxa_Z>5@>zl;j3_|+Kpv;`gU*=!gDh4%zhX&7mkAbVFY*L|N!!A@06|FDC zP_bhI;0(fqEkfuLXdnqpFr9^NW;1?VX89-kmqO~QqQvEwHeC0e%K-7_V zmcs##@+$+k;gwA@o_1OZxuw!HCT=Lf^vT^8Oq=%oj3yWhds=Xy%3SU&3Vr!PpJ*4R z7z7K%wlrVsM@Gqj?{Jg)hE%TVcGVF24(MRXydDAJrKwa_;6-n{bK&oyd(N(=^o<0b z^(b}$1P9es1X?*T#nDQk^vIEGLl`5r{PF5VmNKOXhxQ}c=m>`hJy(lOn*ajOkxQXW zl4F8>7nz-D#F$7%$Gk|tzW8TiOHx_byBqya*-b3QQ71@I9~|DxFPJDw^q-s@@Jxg{ z+syJXjxZzl-}A+;Qv;Rb^{(?}r*FRW9nu%q!ilNV+EM7zyLUkj;c7=FkP$zI9E~!U zhteL3^;Rvnh{1QBA5E&n8$JLc3a;Uso+H{M0Yp%#%H3Zpm- zC~=LCpg28QbeoyU9Ine?Y-{FiD=bb+WW9A3^7WJ6+6*a*xMs`@V`V5fs0|D8@&#^D znR^d_i3!>|z)z#E+=pq?b;&rrQh#2=wQtgortzybIsFS>5}iF{j1#63pSKUV*GzUV zKd}<*+TK%(*=Dvtc#zoDdZ{EyImj%kV|=##2nI-M*XOKW-vO-=AQEeWKH1;}70?ey zi+Dp`(x1*$yhAJt2u=($QMdcW@3c zkZ{(_^PgtMheusTVS%JYS{dCGU>%=syp&u4rqVm4;Yn0l*$vqDboC6L&BM_g#J5z} z7CDj(ObmKqTw=tppudgIOO3_RF|0LUzY4l}xd#pic(b-OW=^v~9kO0EpHyL0I!FNgVG?CT0b}3kikO7|BN~&8clcj4H!Yruuc>XTc zcv?0yS816gL}0Q! z&25RWa{liT!RjNI7m* z?YGD%^f#jnzej*}9sz~`^gVPMyX<-Se9d|I-kO)i)ZJ`!baV(uE*TJO9u)24;diL6 zg)JG&%664yki0$bgME02bD$ifv?7$F?GV5deg5YZo}S3gFN>A;ir$0}IHqFLl2|+h z;OetMPaJ)1uk*w9wzIYbyaLXNpA@xlnAqe)O zYzkW&PE3*LP_ti;hr$F`y>ttE2=aI~_Xn+sb!JpbHxhi51AT2tcU@faHiEK$$m4Qi zCsCnez~13n>!3GDu6AkCHhzYj-%sOEHs)>9e!R0jMNW5+mD*oUq`@jDR_?evj)O^$^WE z{Fk2$ZwoTT?*&T7?^1l^A9gk|5MJbZ-S0MKgqE4Rs_{Gc8`R@7xoki=VsLh~G9 zBc^^QYdUg=$`c(D?*PCe@VMTgY^d;&qBW(}-)?)JEXq2{%4o^PPsPv{e62zyHgok{ zUE)A2wbIscRjf$ftuWFMUGT;yh8{dtx!hTP34BMhiyUB47!7G?Gdi|uX#7p#NverE zxQw+YaF6U~1PSHRY+5VZ9%eCN5#75qG9qiWDFk|WRi&%Y4?#(OL)TJGK?}Js9}?{C zG9%J*Ald&8y=+UDJkJ;ZL2S*AdZ?Kb***mQjqVIRo+<#Exep~iN}lz`7_H8pvp8kV zkyJRf3s1iyMEeVwvS4rgh)NUyO}*<=S?hIMF6)Bj6*L)v0suf&Pk%No+MY3eMQIM( zkuWuDeYS~nDu=6M-{}qJ14`3I{@JA&3~mM{LTQ4<;qf@A&xl-k`d;vvO{^M3Z&ueW znpR*hNr#;fX`M;0|=UDk6HF`wJFV_{+o~ zSKYF^0>Q}x)s5>?611VcqhRDbzWlhZU>FjITC{f@7=uT&@c5Rmw+TMw2KJLPn1Fog z+t#QKgSmi13=ZX}3yBnhQBGdLu33;K%vh;_hj@i{oHu9#U$PackoKfhy$#oPq>}25 zzJtubqq}3#?|xPBiCeKF)gz<_Ig)qjUhS$0nr7EcjbzkHkiIQR8_Pt}K@aAJLA zhndcyIf)lU^t-9N5*n$Q;ijHUyvIIu4qxoznp>deIOFqeIA8}VvOxa}1Y{tJFghro zq(hnwdq;De)2r;sxz|}dV(ZT=^M9nW7|zoA2yb7Cjk{>oUv_(qDapZUFq;knAv;By zEuzr#{E6$Hz=FMIb`)(;9}C^uqKZ6}mfY(;NgPGGwA@v$jn@=mt-E-G?1%W>4f4%y zDdiB-=Vh$GzT}`Bv95nQn8aOjZj@^jt@d#ETU3Y_WU-eBNp;u`LQ!Kke-lT7oWt~lz! zCn)o3&rD4rG2xGJGOY6olR&18w1T&crJNJqPQ7Bz&ZVHL^jD(GB>mMn;5plX5eNDD zCte#o8oiwzsi5vy@OWvbLi61#cPhG;XCqmesDB8vi8Z z`NIXXJKF~8?g%u)#16xv5i*{i)b^SmtzM>mPmmn2Xn4#du6#?MyyP%kfi@$K$u!gK z3qA~I(4-pr^z>-PoPmjI@iWouYWaFw{@C;c(Y7F)>sNMhHFEGF3{jgFXG)Tq z4{nFMtH7sv;@GDjrC^hSa)I)cODp#GkE@e4w=_;o*aB>aYZA|!P)L&jx+AX>dt+8p zj5)x^ZETA+rUKenW1&-CAl?g{ZV>}81~&evW!|^=_SAdWGCaa=8VE{UwmE`t9va&N zb=tl{Jgm)h_>`6{*AY>OIQil7G+X>s`}EJ(i>M<+uH(NZF|a3%UPb>duCiBf zSc}t@@Ck4)Pr6>cfzsxDcLEXqtR~nQmS^pV&nR45WtB%X=7B4ps7a770 z?q%I=JSVk+=>Hhk9N0?0-u4<#ppfmlG3hxJ)`(DVr0r@+yIC=2c6D!*N={z? zxB!_a@BB4(4h=TBa&f;=A~Mf;6-Xh`rtG68Xmz;i*6FQBkDePPnk0~weII)RJ6&2@ z!o*FODX^Rsyzj7v@PyFg@c0OB_QeI7Ow&~WV~=MPa-3U(;Gw8FZE?{Ge}|8i-7lc; zbN*ce`JF&mpeiSG)enQR53Td1xuU8M!%}UYhwE9~uHyBP9|CBMz?r@7CLQveKG^Af z0jtCgovq3tV=A(4D#&%Z8_im0?S(r@D$L=>=w+10l$c%iA|%H!z=t^(Q-iyc!SU_R z-={s^1+8YK=vy_lTLn4GxWH#FwVHgToNG1;s2~>tjx1L61c#rbXUkbmbOF@ZC#J=P z!}3sRxwabeL)hN46QUq+LCN}F|7=6{A{8PbA%Bl!Ut;Nyda^8roPva@=WV-q7tq;5ebZv*rsR-mFST3FR|A~2wjktt7)mO_`-zCqM!-8} zEF2?WDZ;5wBSMC9+O_)J-N^5p!6wNdTLfM8^>N`y3C*=aF*wJ=xV6x1+KsV8jz*T- zfrbI-U;KujR2wKA^{74-O+D+cQ)M)|ooB2C#VNW}jUXmd$UzzcpA9g})4ypIAs&-@ zG4-$PG_yR|mdh0+K4+=b0XdR=^+(NfMx_*neDr(6|rR$|$ zlyX&f$Z`u9o(S)|i-Wt3BD_tJwADlErH7|2p)E<_FWqo^l`|G|)Y$hJ$V(he@_4X# zeo@F_zzm&u@O5VEeW6CKiqwRQMLLG!OPYL*F=2tY{H4s;b~wk*T4Lw$2!gNHpk?&w z1n3SnC_p-d!vZ=m`bf17?|i@LP5!X9>EN-Y+^h9#Sqz(C!Jp7(UGlOmf(8N6t`9~@ zC*!Adi+HTo*TaRT>N@RKW} zz4K%$CO>GYi4Oo^cEB$VO}%9IlUAXH&zlBY0QxYr7&;FNKJ@MF6j@gJdmYaIcHAf{ zFW&HB;M-3~ddnqFQ;vNIfmW&xENHw9qdw(22p&P^-^nMVVlXprb})KUQA?A{8z2S> zn`X=7Ih$!~Aow;WW8YVIj}qqrQZ2FZpHC_NYXn(>VQJZg;oS3_w!T&~xr1t)-5*<} zEt!S`3DWH!Z64sL`s4=fEdnLy65oz!MH4iJ7!cs)g~j>Ss0HBtJB24^9sDAchWcWm z#i<48;ckUOEyj1mCJ42H=3NxS0GS%4NELcJ(s}KC)i*EFgj4;-lG5-Oay3&OOwfN) zTy;bUTRG=~gV7z|*k2Bj+>;-KAh6#yI(046SxzABP`quQl(Gb*?eKR+2XJ3GUzK6E zQ^z|&O_hOkt-?9`{o4>K4ienWab8A6$3uEQBU{RG*L=FQV`sbm_%LsrKQXKCBBo)0 zUQ>tXrH3j%Y)aJJpc%%Z6St=2HFeaBbv8$0i!j__cb(h4V&w}w>`LuMhSyL_*?DR3 zD6Yr@7pXaY1QEduA^4o?={pZ(!vN}DUhjsz`P~t6VsA;~2p02j`}q}CnnW$;8-MG> zBb^3ivxBAi)~|4W6xz-jvd=H#A4f%HvZ<+|&tD@y6*6~dngnH_Gd5w-C257|+muxq4x{vpbjmx{@nG%z ziffIeruV~8SILf$OEQL%3-XIL3E{@_h>$0$>=7#MiO`8M<1iXHDI|@IJT1&tklqOs z^=w&m_1Vxfn;8`+S!ved*}e+G?jk56XhaxVx=RF*fPRfA5c7uo`g^Q`@|0G_-w=E6 zA99K7TaotXAcHksc%#IadVaBkg#@?C}n%0|ov0V@Rg zVu=h3PuhNL1C!``!Q6H(F4;pgZYWQo-3iCq#6tTerFNQ&w26X^#GYy zgA!?b8WzkWAAlK;7i)fAq)Q@v-T}?~-QmwT!Z@Wyu%yyfCMHmD#$S#Hjjl~9x$}cd zumZ}QITxp!2LSAOI=%9Vb7r9++D_0U~pOK66y6P(Hb!xq)hJ!4yLsGW8ZAJ1g8Vl6Z*ExGxc15Hfgm9 zhUp&=voSC^FuO@buN`=^EM|Cx@|hjxElh0_@9#*;F{rrE-iApQ$U4|V^0VaS;n7(fHFG$J>Tl%W0^$giVaZJ?$ z1~U(iZW%r}$A^_`4gpDTiNCQhJbdQs2DOe{=?iEBYo|-kNsi>8k6$6@o`Gh4yczdTn%r>KSgkn-@4wcJ}ge0!_@(Qjh1rngj( z`qqbfC&Ct-b#qD^@fNDMg0I`BA+@Y9kCCd`E$J+s3Y2w~k!RRd-yr|yD>aX>A=&GI zfpQP@+?4Cp+_9XrpSP*H!FCzM*A^vp4$X~!BDn}SWYp4lz1`EKn#GMWN5$44>_>N$~@S59d_`hy?`y?+WsPl;y5*k!|shPHJP%yyhJWyVSzU*Os8;}Hqbl~;< zB}69_t1$Ya>Zy8huU(}xI242cPWOJ^8=o`q6Xhmo&311yoI|kmxxg_9AW2 zt3+=7830=*V|pc&9l!OdhWx|IZkkLc3J;xAE_gWh*x>+DevlYIjysYntufo;yrWPz zW0G=aU(zVT-l+k1^4jhX26-!wBA}ZcN3K%yM5KJiZap5oH<=z=;NtY=kTV`kW{Mg+ zYcL5OodHLP7{pzEO(e%iBOe`1CUDGRw7LjT`A=03l1D7?2QV>^YThWRx;V#?iYQl_ zJ<0bhsj6^<>||UNxU1~1A~C_V^X%V5yXBJZ+Ov$>)b45uuENxm;yT!QbXSIyGoBv^ zv`wAeT38*T(UfFDK*LE-5MW3u4RK{c@o!E)Tzhtd0TSgqYu+wi8|bLaWG@&6+ewma zBbtQp0}or-;B*leS@_dDqHhXUaqcc*7J}l7Uze&kJ5>gYMTtXXZC%C=q}l3~%s0Sc zY(kTghtKEbF`2+pE>+c;8(<`1Cx2AN&eJf#>$sptq+`aCGf@1a&GqrkT+qZ7nI42z zG6WDZaHQt0<;WTrYHHQdUa%R`)%TJC9Dtxe!vj-+Ucq`pl{d$cTbesGj+S2q2i0ed z0AG)h8Y$j&wgezCa4|4CNW+0(O*GfX17bw$)UF^<@+`TELPJW}f3o zjf3u%S`A%p`5Db&bdQ*?g4EZ?W7lmFuCBi@B4r+>IJpR^I^^Q&*xYEwsH^Ie;h!66 zaD~}^jAzJSg2+BsQkCYerS~er>p+)-ZZNQ`u@=SwfGawr^QPmDa|@yKOeT$+~>dhFu&&h`6;Dr<|K!&kx^gusT|@er9=Bg!?% zsI&0MibPxmkkn9`5J0%In@o8jYck!e)ro}=n*0&Wb+PZc0?YA&^M)BxXEUv__q0Ng zAPnJ2OdYnpzWkAWm$R*Ptl67xE;nTkn`V~vR>t042H*pRY=~T3Sh3?2!E;k@sEc=V zm9C1KF!8jG=7O4dsrB<6GHa17L5?P_2`EtyRL7$B)mIr@Rphckn?iV4mH zi22+<45g+EtcF7{{(Xq?z2*eyJL2v)%9>Ocb(RjhV1`Y7)@mvlj1e0|H_~P^CG)ZtK&&}D zVwymL0IH(xg%2Wj;tkqHcjCRK8|GlxWfM-?Eyc#}Z8^(lcJHbSV>sQnG6P*Nd%@L^lcP5b%?*(AMSkp{PaH(%~s+1G39MXl8t{8)|L=z z#kc9M{cyImxY5~iFHgzSteJH}42r(znq2||cy)1$PFo6M*C=>2Rke>QM4i83h&otj zblf`scvEZ@tErL^vY~J>dW2kJGOdQj)glq>sb#rEN;5T=S}9~^Lt&sN*AHo1!ioY z_Q7CxBGSyI5}NoaSK{~?i92JZUqzED)&X?Iq9LI~_`;V63MBxwJy28*Z6FO0CaKuA z+#z+u?~blr_aY@nuRrZ;8^Emz02JWLI9?rlSpa5c%1zf zlVvlywMXbm2e6j!6&s+yp8=O>`Vnx)qfwBQs*w}zI2PVJy0NSh2DSbT-{Kf-MPz%{ zpb7h(qzNha@eS26f&^c@)u3(`39?@C1VIpq$#WL}kSle#BVLdvqKH5bFP&^@`U=LQ zz}_jV@2IrxcA|m(<~>n{11k8r=qMLyc)9|F?0*p+w2t<#P)z}b2hkG?BVVQq;vOH9 zRb#KFN*5PIw%%)qY4X9=Ly>Q7u3{Tf$bfA6T1q|XvBgJCJNGuAu(SNccCc+%z@qgQ zkYRw1TQJNpHc@z$E1_OZV;%YSnB#bGxvkuC`LJfe@f;{QDSW@cyDsuhihrZcnoXW2ZG+Rd8*P$!%Ejh_Mqt{uS5cyA|sux(uQmalt#s^6k^oI&lw?E3`{x}s<;Kej#4r3TlwQZ_v%Rgnxx z$p}Wq=^diuj|V`UGwXVtV$}HLh~|qr7We@Rb6Y@y1tKumJB93kGKr591Kj!m&pAv8gbf)6@ksy}-F1~3WsP_i&?xeES3dQC$og1jJs%Yr#X zXsOAk6oiPeNk3)UAaVYhd{?XK1+eiOrb}2f`D$|rX3WKk%BOS~w0Bqjb{q!%M;a&6 zrS$l+TAkwgH`ulP$u!C>|9ftzdNU>ZudGiVtce(YRC`=|U^OMjxZq*Cj7b@B^(3!+ zuK`*)3_lFlvtU2NA+I!?mf}=q2|W*{h3f2xZiF_lWFU1nXrnXVK|W4JLp=XTy-0EF za=_BMXa#76cq!d$oLd4A#bfEpJS{^cD1*^BD{{orr4=92Rq`Fq<(zG6E@BJJagHtS z937nr(g$n8ECxMNRW%)A)uAIJH67$MTDmQ4*EQC;Y0?!nsh?0P>_>W>i{lIm{+~SL zDkIk8+T8cY>=7PVstK>_!#ApE!%e##F+k4kvhD>`|iy=rhu8}A)(OM9m7K`h=`P@ zo?H@d@@Q7b&vsRR(#YAYyFg~73xY^H9W7CY0xXCoj4=d6G|2Z_JaM>qTa$mDaMx1C zxtPa49T_PZrxxamiAl#odHL=poLZS5M{Q`RDH+*7r#mQIwGDlA;R2lU#5se?ET$3v zQtY_BB%D`9XGf@ie3p9bG9|hdq}Q6Blzk$dbaQDF3MsTc*QN-zxA#c^HsYv?dp(IM ziGr+R9K4aTdqu^l*_?C*WK`MyeeEv(TGa`wwfavUq7Yfc(<4~>1nZD;R`iU#UMiB z547{XSYO0lXz00#54NUo>LDq&4RnT34SfsyKUCkJxuIJtd~^<`T^tt3S`csO5&?(h z`lE()wd%(=0kjh?^FHA{05=)JKMO>|U(Tr}vy*2a0cqs<>E50@T&jSf+1wpj z(16u-N6prQMxV9jC*5jt6O)sI{yq)@cz9{FFZSymecM}K6R;Q%C17AgPm5l81OkLE zfVPg{dEjB@hKD{n0_gT-3XY{2*j&0XwOvt!V26;|*LS!jLh66?b3RiZWpAvy<6F23TPZ&`-K;1m?59dkuhddI<+30 zt^;;Vl$7PeDJldY3e9&Y`#&rJmtuccZcKS?;xmr5JzQEsl_&;>TOzA z_4L|&Uz%_+99Y_E7QFurL{)z{f)FOAh?E6}4i_>Mxt$T^G#G-6%}h5}ZX&w$So;+Bmp?twyAIT>sX zVaD7KC!|(^({c1E_g5pBiGe1>E^zjoOCFZ^4AR@>tOi4-9}Rt$J@g4elpya-9AQ7B z9{OuUTvjKNxB0em+)n`dR`!P1Z%(3FH%Br}k7qIN{)BgnKe}GajCWxG5E|3eygST3 zvGHT*v^X3peseLY@TVZ_`q}7%I)2TR0-I#IMSN|&-C2eN>OJe3vwzqSq03cF^!}f4 z-4$dcNKPczl`df3BzkoAVmT`uF))uQl3%*6z#wqp7noF-baU>ZU%Fe4d5A#*?LX~v z+paii#U>R$Dv|trd*I1wjB|3PgHRZ+B9t&l4YE!rV_qstLK)*ZqinW7Ol+wD@Fmzt7{4!lG#6*oU)eeOq8$FtD=hRW$V@USm=JUy>s zk3@c5>hp8%0g^lC-SQ_I53qh?T%HOU%^Llrj0bC&`2H?u9l^{}UC~yJR4NBGYYsPn z+>t_6BTw9a-SpUNbj#BAM5N*V-AQH=!=hCHre}`1!-S1jrl#i7%Rs&o9R-~4~)9}6nnBW5T5I~q7gi;T3z{K@0}adMN>Dz&%R>+h|-zC#P0d22v`@YHD%YOk44 zp4lXlXlK-S&Qhm$Y!<9B$k6l$UW5TKj-L(?E+(%X!IRZ)jynzU1FsVj)Fd}CpBRV; zppSnV7W~}mAw&jI09j6#30hY0&f5g(y%cHha5~Y#1OrIuX_#wVC3 zZO{@drPiK1zCFEZfw6yow5+sXY6K7ygb)sR_dg!~K_}&u73%#Nbqh@U+VndZT{HGLqpL^ zK*2nj3MKR9{KqaNve@&nvKP2nXK#t+z&{H`dro12`R=1~H7nc$?lIZ}VB?P|I)Xc> z#F5rF82MfFER$={d{NTTEa;mVRnZ5;=#@RJ5xXLlN%+wFmUu|!*#=Q^s_Giw=iXDw z5HM|VnR=A%>J0jxFdy74o|=~+IiFMKkSI-}gCe$)+Jq>W$qVFjHZRfWueP!s1vu#T zmSM55aTCXQk-eBX4pYzidTNTy-?60h^#RyXjQ7!JNoheT4mpMdxN|v@#6Z`P%r|LV zA?Ivy^h!y0c?||z?FuynK->~37Y%8eLFw-M$zNT1q;5n8^=eH2 zuj2xcAb?qk=Ep{ke%QAYGPhKDy9=zL(0(Nx>BEa0OgoXWt4_3hhGf9u^3jK45lYc3k=51}V`zFplS_Flo4ATOlx|}ZQN7Oz+4fqR>N>?ktDr?eNY2xT zw2Qq1v`8&#Qf5o4c<%=BHo3vxztl7bdGcUzvp!`}?)d_w49^lP*j;n{PBgY`dC|#_ zX~mLSXGVR$z2D#Bb37-=+lsPEm8A{z8JzK#qoS(}eWuj-`?2OtT`^OX-Rqs!l?c|4 z-Gq^P%;wP13Sv9ndRhF<6JJ~nk`yj*Fx)#McW8Qc*=8BV5(#1Nr0-_j8pwEk{2_$+h$dNp_;ozGWU~*QWZe@Xmu-u-Jo}iZdc1aj?10AtLs8 zrRwYLkNFn76&eB{wOtXc97{^G>Qn46U`O;|GMQ;l?oaxiXb#d+phalB`E;s(DX(m` zuiRCWv|yxzdFIyVdKEis`;kKO58~&LpnJ6abDO3@7Od^o;!T%KJLpHw@jI}gatAYVfLvP|=M0Yx=#?e5@EF0y|7zZ?O#=Jz{ELI2+lOq42VG%(B0ilejlKEg2 z)cw*FF&BM9vdde#P9cT?t7TRmd<(eE>8Bn(gR(ARP8fpu z>w-D54A5ej9OtR@*O(=B(ZR7iNN&rk6zLNQn-1u_vuL1}g%a@q#Uf|xub55R(Bkgz$5nf!h|*^8@Ao)8xEkyVn11dAxEVu$ z&`8`eTD`#F22mcZ)F-KlF$xT$gNx%WU$eJc4AyJ0RUj!rt(=W9q239c0je!H4nG{E zTy#~#P(WjQP{eN#*n;TNge?C>iGmg76g>wyaFHo{>apr=pRX(G{c3pInoz4q(TxzX z&f?ZLPQa0uAU>lJp>ARxIA-!O=~>i(+>{m{>B>*6j*T)cyzFDL%*DA`eWx1p^@Ho-%QqB zea>t|wb4hmp3MjG3WocXE^IC)*g$EGS{@4O#5$fMW*7_AGzK(?r02G96F}h}60@IE zWO7RBU@%F;)>H$$eZ6v#5WBr{_*1$=e#>{~&iu`bpAPq^4nyk%;@CRF*d6zP9!v5c zcyZ|G8)Jxu)h)M#kg1-jSP(#;m4&VbSE7*en@9OLXk+MjH5xv5A^2UbxA3CMg_U%_ zJrGUR>vECF}CzW zJY-KWs<2ka2p~*Y-^3yKg_K5fB|@q}g)%(7 zN16^jwKq0hh=aRT;wifu81+}<8U(t@jEGIgcSRbzllGo%DmwKEg)G}&N9#oRo9G!KNRj?n!wd;-_{%jpDjT0I z-ig--=Q9`zC~ckMFg79G2J1rygGXpY5>li{Y1mvw-JLvGkp>+Y-<>bfdGq~cwtVHT zr(?%HsgT>rn~+#nG70msus8euglFzA9o!`U!*M(+^cxRGug80 z;DiyHmc!2Ahe3?`R53TyeQ#cPM*xNB`O+F36J;8oZBF(7ths$`+(P>9UI9bX z?HNWL${F`|?HdsY$v#pN)w~M{UIcLiMpV+y$EG=f&R%=7vM})rf?;dLR-zXS(0tGb zhE=}BbYWB|RYrlWcwGyMzog~9+J?doq_38r7Ul|l2^0N2p*F! zx;6UyPZnx(tAa2jR711#4S4L#psHJFiJC%D@mvgaad^N{fldl?MG)sWtlyb?T=%Zb#DVz z9GeBq;L`m4?i0$l&d}~WI$d(l^_$^>ndjufwU_x~n+{qUuEQvoT88Iam7h6Yao|6h zZ530d6u0IABhCvDbGd$ab%S|VoNE(TtMISaG1J-Mj&&j1n=^S^p~N~IyveoIr+QWU zUcR*hr^{5aFz*N*0}Ko(RlBoY&}^v7n9dEBv30W(&L0d`{Jr82`BAniBZUa^R*T1L zCw(!ZrzmJfEug;aQ);!?)hP)qyCmd+(=ZC7bwgi$ch|m=rdL~rB)hU0U~Y(QBkf&Y zf`(P4dLdYz$RL+=B(r)u$kWU)4oeVwUt(|Vc-`KEiMaBV1FR*GnOxQ@wVHQzE6%mk zWc_8IdPkmJzj>J?%%{`VrqG|UP4&n=H!viVNKKs0RPDn_NW9RKCr7qNG-~~g_-6Cg zHpl;)TcS~nT(oyRYu#Iq5{ao3B@GRA(mKF`1~@=7C0{lnC?r8CxoK1GNu9Nb>L-$( zz1ez-!I&N?^(V{CUvqQL?jc$B6Q8CFXg3IJGWl21O_;(d9BKFZqnkTIeUy3%p&S*0 zv4MiZS1rfRBbeJ8OQn1UL}j!>;A3rihfurRfuM~dp3;MY2o_EF82--RafFIfjm(w| z`dl_EL_p&j7$O!Zk9k&EY>8iI&+E~zJ6m%$vHrsR914iqwKxbJyrim~%#ECxFE!}i zomgRjehSR$mc=!#+@XX@WC;QPlJBT$wAc)m;^ye6tyg%yWmF@}pm9o|pzfsns`V1G zCW$A$8#*F)oz{~exoGd;bV^}?rK~?+!&X)9;O!8Cmy55y;WvYKtiV{%B4g5Jz>OengTEw@Fby4Afs8weL?{Q!u2qd1kXOxA zjhh;B{4mg}AFm}=p-*E&7!T7Giq{ff8p!lE0ML0jY*%X?4Mz6UrwJ&W#J4J^Yj8m0 z+dE|)PAJer(%}oHeEF29;6pjh(1ONilgocyS)nfJ(Eqb>NXTS&lHeKy+Abd%(3uFG zAqXHe4yOdaYaXna^B}|dH4X3pXsTWU2W<5EK%uat?fX#%&KUz(BJ##Lk1fYl^EbFHtbmft!>uc$n?e!1U+}7>GS? zz6>*<^|5nF-B*mXHPn*f`Dx~lsQ6ZEKRK)%Qc;{Ii{RX^VqqU zlz1Z;Yce06c9_#jRnbkATSpF6vh(}A+e}_J!MXc~zNDs%t9g@(^(`_HS zCO&JyX1ocWb<-zc*pd{6=?VsB=FsAMA zOZHLLOegve`;fRNCu@hS?pJ!rY+D_{+hvX;@=p?4-oIDuvk%DXLE@u{X=8icLlal3 z$Dm>S(Qk!F`1k|tzxKMH!3Qw%?;yNv1D-k#^#k*`QBP#SPW9=t#uv@UDhgx2CN>i2 zm2oK9P015p0=}NRo#INUArYzIKIXAkQjALL-*Cm!R7NPeP$QY)TgxGXOw@2~`-44$ z0Ok9{@S1>O=25&L5~814CTsZ+&3N>J39*l}zsbQoZG4+3)hynI_lQ z6t&lPh~%G;y;Nr2yux!3V88%NK(xP_BH`L%z$oll6KGz;I>YF*BOrnUog!W_QQErq zyv&BMUgJO;Kpu8C7}X`rs~3ltfx|0$8%Y#x8*BVjBfTir6{EwUI|c%=Cnl-L3e-i! z{b)Puoq%tsyY=f^*%m1#A{4>vKhiz$jjgVdp;b7EuBuryo)S3#b;EK#{PgXMf`oJ` zvUaRa$=}Q5B3f=3rr*({uA!t1LyvSe=qm6jS-m*XRPqEZBDo(-c;gV}2H|%%Eb(JM zy@1F7i7t4fS5w5u42jO@%w4W(c)Y)wwU24XmJ*#dW8MeuQ_GK|T3f}iKy=b$)vV)${d<)re08hdTGJ*UA^N&+2m3a=us z9R^lm3iMl#jdCjSV1H0_w^7?wySZSJF3%VJvH`NgmvVgh zL{;-4$xRCBGEa_x5Fj0a&b=Kx)R*e40LfwHS*_&P^kpp4h-GGpO!R!b`JMk0qrX}> z^P@<-QWp6FGXPO1TV;_XlKf5Qmx|_FN7JI`=Ub*zf+$x5VHgU+v_j1E(u?g`SvQuA zuhE3JUDnBH(^{>`vw+&A3?A1Co&FxTTk3u{@lbzvMlWI^(Gd*OcMfrt2tJ-0!Bb|` zJFvvda|?bZ!KWqZ@_kjk*-)hPZF7UWof_I|g`~`1(7YCLc+2sjw${ZLr(d+r?^L>{ z@>S&$t&IF^2TKi5t{l`ph+QW|QD-6HLL^$36iw!jYVGuhvwQxqolA)U3C$y=4oi*n zIs!eCZvRFWnhrzA+X7Xj;$ellfpHxeD?@`;hVrxjZM?%Ra})akqhE|faz1_$pbed@ zWD^OWcR3+lPS2%gwhlCQBjhSc&s>L(I>eMM*}&pPhHaGJ0I8Hk9wyj?W)Y@!H_cB( zW9=EGILCqdZ$&iImc*@?Nv9KW-WZmKim;L+v477ypZyeJdL?;2!;jS}W_qPRqp$WK zzoqS5881$`uBW=`fjZky`GqWK9x#t+x;p89RRym1{L1%ieS(j1VSan{4iqC7@XC|; zsr+Ny8YLWKd?9eyD)=0}k%?G01@&|HKrjeX&A?koFoNoARWV3(z%i0bX&xjemKmyF z`i8s&SjGe@ymT}DJd#fqN2)8-7khyZF$H1vrU3rpJfhg>RDQ}nG>`uGkCJ;ZXYOEi8v{7{?PSFR zDRr998M*l{BYm46>0^4KatYfsp1;gZqGyFyAl zywU1>M5X)qy(Ua5vi0|XoQ(B~n5J-V#jgMd)h8MTa4(9vi9 z1=>{DGB^6aV&nd)iCfLclvh{rW819JAd%!5L9XXfxLrL2o|zT!H?t@+(_mMt)X+6%oh#hV6jpT4+Ty!{ky(Pv&D(WV$tc1 zBxsr%wj#e&&er#eyVxlh^S>dkGG!^_%%scA%qqQE5vwj3CO$`OKAOSbvtRl> z%-stcKzsBs-Ae0&t@a*{>-1&qq`lt>p6iz3q4*U_!0-qUojb!@&1$2Z-UPtf{oPnk z>g5lVO2Z&;3a7Dbnbc{l%_Mu@MuVjJhV3K-ic@djG|K^szv z4P_NnF1yyXAb2nAO$#>Mif=nt2jw8X#)^!>PVsc#x8XVK`?r%%=}1lzCxAcA8>MTmof-7a$PTV$Y*{b89&zC*M9 zna}!$CLFOJ$Qqt5y>sI;5$Rden8kYuVD0R!`1NdE%Ub0Q#hP2Zvulu3^!i;5H|o_L zT;39_M1v7Fr+3*g%WW6{2q36_ph4^Szu45JMF)@Xk%W`0yJ z=G;mfeU_We!r9aMQD>} z`bcWvVh!bUW#h@SHkasBQOUa-S1!wu`p(`1(yb=|?LMW|qEo2c0O?YGkM-PCJJSb= zvIN-?9xqja@iCGI@Y<^Eoebr-q@>&6HdEJ%VsA(_1^I6G4@rNE1tGB#q@lF83_}Y| zQ@!@qDW5EOD$NiBZ3@L70m@k@o8Q`##2$ZWgiq&GWt>V>93tu(2UU1W0NqmxORsHt z?}O{FI@`(#=V=yvpVMoIUar!mM(+;XD>)n17*ai?Fj3Gg*=AC}&(F30+GU`tA)2?_k4f$alS!{3L zx?lLn9Tnt?nvxlPR)(_s_vnjew;;tz8vrnXPF+16YcoAMSw|C#YJ)-yYz*PD7nZ=u-Lk6u-M@~(2?F>;*{ia+dwJS~@8m)?yYnt! zJjXjGwk{V^Iw=Bd8@3GEJH?z2j`mK;t0{8*a>JaLa6EZ-b}qAT^gRZr6Y z7$d&9V~Fj9I7^{|fgpFbIDBK6HjJaL860wx7Kf+HXoQk5Hg!5ZLKd4Y6_dUuFy&|f z7EfQbwR3q`vciV@yJg^>{rL*WMGq3WiANQJ+jf0!q+fw^o*^f`aq)X zvi?!ozgTs8+K$$xjwJ{x+9j{FNWuhLO|kxsYdD7FQ+tUB@+h5cTyu%!s+M`G)a%4s zU66Fq!akUCes28RM>wdt3SL5{LaxHBiLaxr68 zWaML4qxz5dVwD8RQh0Ti2=UT9C+Z}AHKU5(F2t2ox9E9jBu{lo{DCm>zx@2%u8K(p zjjkAn4)n_O^6RP{=aC?x{)}N)RM)LE?8)M4{wqF?I^ox4eooDf(J#hdiBEsGUD>vx z(TT>g=~n2|)O2Mz)NpZO@AIIurF*1cJC!YP%)`|m^Buj~UgJL_P%GWkb8Z zc}3aB>=PVdfx?M15;*H&-qMYL5|2&GX62_8Lq~|+L}PcmHS4gSe{+K=dV|$B-p?8J zKA6P?s4wp{?@L{DL+L2$RzhRUgCSc3!IC#)TcZ5I;-AzWFIiXks&VrEmLvcWJBSgb zdB|48*g%YnU(a`PC6Adpmx$)HqRUGVw4yBzFo}bT`+GbQdW$B9Z_z4F2TO%=PTkti zN>k6P<8NR7{FnFaGOx#pZTuxWjMrJWw1^3#Zc$D-Z~!#{vWxOcn;H}w0L2bi8AP7) z5W3w1s960Q?H5lrDnn>|ZiMt|rrjwb5WCFzr6}ytw#Q(ZIqFhYFXrO{ zqA=5AEuztiw#qe?u%c+?m(mzgjP0I1ppRs)JXpG`RMfLxb???JI7YsaBm4CUhS1sIezVP;^0*!^BIpGCv?^cGa0Op~4>C(36y1)ei3bs;Q%!k8sEu+< zm$|$|T$dJ2tBx^zs;T3y+}&@5ojE?=8U}^sEpcT=WgP;H+1bfvw1jysZpP`krOu?s zAvzmkh9dmxT5kKiIDcy+i_em{z5zW9XMEX)6%n>4cZ*!Sn6;_{B{C#p;?lU5<)AOP z#m4eh$~bH6URGcVZh7SPSHfc7f4v{r%j$TlKiNNo1$h3dxN8wB-8-s`#Ko|MC%RRF zeC2+p1DxFk%331D?h(2me;$h1mIWqvo`VWEKjKbr?|oOzJA3)6)*_6FJru@MjIG{r zFdek?ihYSkEL{DOwJru15rZ;nu#n5e-`6{%-&~MQ?aw!;Z%wdJeYZi`~v^EzY3Lk%rpg0&yGRF?iWC z1;)_!ADm!f^wO!VC;FG700Rbpw82*FVdOp43+MRk;9kf$naBfivs_xBUty9!D47lO zJEgUqlN7tBZCjB>Z)9LJ^clbs8J{PBFi`{yr;*#iK$UsYb=(6YsPIVnNs25CkX&>l zbNw7iGno(22!5YAD5_2q6I;kW>x%`R$JmFbqVeQxgb{M+UM32li@kTMi-KypBL0>x zlQO{Nnk8dqd%*4=7b5lpolyYskW7F|(&QL2Vzl=q!9@GT*iZVw;~Cp2GL) zkN14jE6o-Fqr-6kgfuMcp{oVm)MYyOZ1Jr2Ipu|e4s2JR&2BLjw)C6W1PB5IZEQw* zU-;Jf00<(QcU-@=@()%*9VPa{We&*1IrG=Xip@SDc`mTi$6=JHtu9KTJI%5T-b6f28+2> z!kUL8>N;1M%7ScxoJx4F*YNohcVD+@?%DYIW^qc#03d=7t!GvYX1VV8=iVNuJ?8h+ zqve!QNIJQED59l~Mu#51mE}GQ_x2Xnxo$>&bGZ+Kqx6}tygKrooNr(7c5@A{4&r+Ts;)N42uUi$ z>{p;*rjL7`Qr~E%Zn8HYz^%02-GgZ1bSrqSF)KQau-52*eXC=C=hF<5@cO=Vt5xqV zepu}@{ERRg8VE;Ya4j{$vr_MNkD%~hZJEb;t|~+WAOV8|-cyBh!|}mV^P0qd;M#~p zNL3s3B_B&_0T|d~?J2$&SfZWaTYb!O&bJqasob~w z;Cv~BE4d?2c9TOWwaP+3tgefxYPCQ&SX-wzJGot)fKB&l&+lIQ7)uEVJqCP8tyKt` zH${c!vLAU=BE1OKbtiHXVG(DgYpRDBF!j!=dnbldZm?1DGH9R#9<}?Im5ud{X27=x zV=7POO#k8G{R=252fYrE^+-^A$a%8gvy;hFe=O939bYX5oW#wa5s(aG+VwWlgc37JzG33Rn$#9##* z+_iUmta5%%(bv&dJH4%@R$jcEDl<+5Fh8qqH2R=}h(-)DN-xZD0e$Kt%1X5OHyL#)Yi65tvIySAVv z=WvPpIC4t(kG|Tpn+=Pa`|$iY{^!K<2NjC$u1(?IZ*NpY{BI)6>=}E%KO(FZKI`GX zsF`WmNz~YY;Rho&hYAoppJb;cPz1q^tv2D_woXmB_^yJ?d5x|E(3@_EDd=AcX*%z2 zqku4|ESLiYNl@Y;DiQ^O$#11^;r2pEj%dDGjB0%|XSa^~kq3&byzd4(8gkG6qI#qx z0PsBeA^N@JFjml7(W4`i#CH$i2>XnVAx^wUAnCLN3nWqRjY4;w4(jtjb}WQOSl_>^ z`?&UN8+U12v~sge!0sp_WQTt0>(8~^;Ta+jj+vm{<+wZ-=(Ka$zyVosydiV9{da#a z?qA}b&yL~goA^42h;lT=v%h<_a?XIgC1(*02#6dHk-~8ucOH*pi>JNG{)(I1UwiC- z72nzNdD7c#vVV?se#@s`rph}ZjXm+#jR)x##1fUPn0BEG#+)eY)-o|{BFe#n6*{<1 zaZXgHejW5_^Iw2LQ6976j>}&8^~zb#C&?~>MLESk=X7nIESKW*yt(MnU4k?cev@&Uy93^0V;V@ag;Qcc$48 zHGs9!>|)+ImO^n$KnMAvLw*eGj!#}Jm`sOlc^?m>>`dMCV9v)?| z1bM(AS66Ol&J^FWghUmypA>0>5Gxi6r)9F)DJfKbc{(rL)}zsVto2Mj-Gc19*H_t? znrE|3S z7zYORcKzu;BN!sMPH8e#`nVOJrXwu^zvJgUn9UUBTZX=OQO7K3G8Tv{s*xJnfa(f= z=%gUGl%Yp>p;i4Q-rzI1cz^)fI$$Y%BLT0v)VWE-RD}|}|95^Y`w89)52dAycG>3< zdLL@t)aJ$BO`)>HwP#-)*b!J~?sp-=3TRMzl+D$FGI3(8x9G*BeC1M5k&*~)x-gK) z{P|?+Jwr4b0LeqjBT4z3{JmsabAD%o;=tx5H8W7L++R=!SX1X@d+EnKXY7@CO-qr-TFvQ*~8p77B?OyI;}Qj~-7W zf7t1e#l}erN4jLyees@!V!XQSm>Jx66=-|zF?`35CT10r&4u#`FWW)sg^#|G*5o#SWB#}%`ZrsLIqMURw^x~01_hIkUGH?tz)zdcQ> zT3mVc-O}>Cbm--cKI-|0s?Ck3-3uo7kgSv}a9=mb1FM%+GZ&;VLU{arcCEhv2oMTD zEg+hv@W!Fw59*d24JTOEQC0PU)$_+oki7c0{{TmrC^ z^gE4TfvL$Lw`!}uKI1jeaNs;P;A$to^5+YY?7_i%^6e} zAUhgDfz&(`l`(iI8xS}!cg66w=h8nYi}$9*r$rh(!MlyeAF%yNz^@(nsbg>06}p#A zX;9@~)*BAu9tu{GN{m-m)Qc3Wypb?;t0nKN`JdWmoGWC1XU{{HA=pb~KPjO>`NtgY zF0Xz+KR-l3Y70iyrPv%O_Q2*7x|V&J)AvDV{7!TroV-~5&hQYJ`tMY@?H)Rk<^|G13n6)ozWie~&^L@74x%*w_^8ai@h|1+ys6J%tq z*rPM|DEUfnmA|I74mZA9Z-X9#tJ9TfOT*;!woWed$>71A@$#K2=6xV~}{57PvNKYGjk>VWv&;BN1NkSDMX z_=C~-F#&Nv=67st;=wo^-Lbg-U9bp-_ZYSA*Q+;uixq+KSYI}hSksQ#ndNwP<>1+* zSn0;Mn>MM|-Ps!3)2b@O^;RqTp@?~Q+`!lUx&k2aWOjqUKpc(1Vo4YX-bWj;YPDUuBOl{T`HvKZ6~V-@6_wyMm^Xw zT+m}MTm2$eD*fD~O-cjPR=6xIT5o-$^Ha zZ$}&$1#49jrQamIzS)XKD31Wz{i{VW@m+V{*QRLAJ>{He1cBA%m`RE{&k22*QG=m^ zf<>E-1GcfM*w8J7K zDSjA@f0Axr*rxO<$^u*6m-J-IK?pobP#^Xkk~rnvZ--dlMdZ#*&VcO-&066{7n1F4 zW;J9|`iJ&s+InS}hA@wBJId0#JYgNXKg+V^fG}V=AVMHW{4O6g(%x2yBW}y&?NAJu zmobgW{UNl9IJQ-X+7&IT9p^RIOua|U9$Wb}bhWm_Po5tnWWyH)lYXGrrOEq1%pN1! zeJzT0YPp1V>rJ2!`*%xuhD!V0UvR7Mpfr(NFS;X;L(cppE26&W{R>t_x#`s)0(<6P zuElHt>vtXn@&4ls)+Y{^X1L!F<&ul|@YpPPo=JnzvhmP})VOE<7NxML=aA*@BllIi z>wQ5>W@ys@`IR!~ zvzKwYLU+ds3Ai94yLW^cQknA+SV7Cp76sYVHcma*^LxNwNeE9c2mwAfSo^#p-VF0r zN9ot*0p{2d`Q-km>V__fk25MxN2K{;w76&=n=f}O&K-LZTcHD3B z7LE8Bjj}F{YS>-|$Cn!Tgm|X2!gHhGlfxpiP7g+K#1GS#1fW0}U9M(QjXfd>E};1D z@Uus_m7c(!8wli`3eTw~jzPA9tH%D7x5zqD3$^3Et-Pb7%6pG}|3j6oG>t;xoC3`r z<=?X)?vC)rvzlH%KRdM{%HW*S>Fj?g{QYeaX>W>ZB;9!TGU+!3RmZn<>2%pACvFwJ ze2r7HKjIp2?K|zy-V%Z;9ZxO?aD3}q_D8Pg>$kn_g0SmHLjp=^DE8J1ts<{<_p&frar@ggP7zXg*3i*wJ{JMBRpm9RAS zkM->-vS+{t;6MSzP`V+LBZoT%l@^}x*gLJ{Up9JB5ahyOmzd+kY4leM}GlM8YVd!9Ohqu3P30HIIHAt#EFGilt&r+(n3?$?CHSegFPz^w%MfS!jwcf?Zg%luT+&iUx) znlM)DlH4Cn6XF0t$DO0|_PGE75<;KuSzYO5-*%1A@eFn8FF~K9o|tz9QoH+_O?G-KB<5?tbd*LG+mEKOZaE6rW~4xtsX& z)!SIITQ{fa?NBMpibHc-T3qY!AxzjJS6uR`H75hZB-73aE$jOHA zIhoMj%N6W_X_t1GRIdm(QbMV?cX2%L>w{zIM+FdBH>Ay`xjZn;{n-uP$4Q4oXLnz4 zR!w?mG~~W+b~nmVwS>$NB^YI}?5=#fx1B#|xsC;6%QU<(mel&)m(H~PT5ikv!6)L6 zxvw0+e7tGd?kzc*;B}R5=1~+0PhwcNDnrp3(Da`tys55BGm*b09!3;~)nveog;ug# zk!vqFriUiUe(0n@S^X(u2%caodX#*7Ib0e@L?;@wCb}c=*c;~HWQwU9p0Dyrx+>C3bjd19|a2d{VZaoxMsu&+ZQ01xKiZGVj#9h?st-vJMSuH(i5oh1AWI{BDHJSyt11c&h|n{`S;ypX z74?_Lfp%i|p^t`{8G~#>SL@)pD!gvhTr&+~Y6PqSp6 z0ARA==z= zlapL!_s?)*e5@{h^yI|rie>?(uri~Z+>FsObJbU9pHMp533i5iqKZ>%Y6`}uk6 zeTAq0DD54;`2Q}Nl7s$~F?7p(+{SD+o;TMxTyPPrHMWI9QC~9QGuTp`b~h@efVKo?!Gl9V%q)ANQ zy81;{RA_lj0$gPVFmnZ9N7Bf;jpTeq3I4bw(HQSTuyZf19JLAN#MT=o^|PXOnn(Jb zB%J!r1}Qf!@-e%qT?!mMtkXo^m&=3A3tDj;_IV^$O_^|%=2HQ>S zc}trzN&(H)0kvI}6;V@#D=IeL1djVof0|2qvc$8op?k^+-%@U=qDk`2PaIUqc$*D*xouZpg@bPCOb_Rp^QHcm z8-Gk|g9`T@D3I3^p`d|6I%NW(0J(Kn2;ZMj<|xl;(q?+syErv-?$bX=9}+)D{NZDU ziPtm+mU&-~_}Mqxgm^_X0RdBxDpuQb^v-In-Yq$wNDseK+QKZ0r7PyZE%Du?J$VP` zfSeA1J83Z?l{>@vq1M}b0WA4?2I10-Z?JsA;z3$vi-g^o58o%n^=GC1=GO2M9;?4c zQT0}H2Gi3!g(2oM4qsX**W;^KM6j-bhsz)VXezFk+@ zwj%cIAs(EaaId&v*o6?!3duZJ8J5`u>YjFEv;6>VD*xhI*CG%={dGZ}#+6NLa39{r z5z>;Ll>6*m1EQ8O!}54GV16+xadS$yM8p4PN4og*@VRq&1bi_+fKSQf!XYdV2PH67 z(??cfBQfsA+qC4cbher;$$8Fq#tm<_{6G*=zHCD+iLr!2w<}y;oGJQout3h=;e0~i zNb<}Pe+(gWER|WjHs#JAVqBZ;YTq8^;wRtIFMpxA*}<6j;lwP!TXLH|+FIxp9rG#( zi=kg~(=J(9a(*%=Wc1Jd%IE`SMR-`-F@I&p-|+8ImBlWqq0sL^m&n@^lb1S7hw-!@b(nsgWVJ1$GbcdH_;){-CGv`#D=mbzF5=&OEuJsc59t#c{$qm z8h|iBOI;JUK(dLp%rukFKRxhauV7BYjokRv5uZG-F$y|(+k|Taue}!qER$~M8(+#G z&!bfzB?#^Q_rO5B$l*brkD}W0Q&o3Jcf+Vt*m6t%bbPLm2^>@z_=i-z8MQ;mugePL z+oq#ONDL4_X0O`DP0mJsh3cyt7s<6<$~ilcTdlA|^1a}pBUn|zl{o>f^6!CCGuX(h z5WwCTFcFXP+SC>gOBc!+>KyfP`L=Tdj>=K@cq$=wjH%XN>kSP6$EjL=z+fts`)83( zUX3H%@6#@o%o|b7%-^;$tIk$v>>1VxXhPrUc1Qd$VD-$ZH!mM$XpFE@#9APG@NKYX z$o{KfkFMrpxO(@_|DMKT2ba(4z(ZS~v0wL{qOx6b)taV-CG(|V7c7eN3`Z6m%>Ri!te!}Tnx3O!# z*iP@^XaEZ;>i1&cs&ouFq6(>FHv35`N?701kE>J11?BcStAD9X!b=0@%rQlAC~^0W zAB!RjoIJ{HrNVQZFVQ?}feuSYOf0QIc-G;(-FiUuP1O_l;Q9?RV@ZB?I;@CC8HZ!O zhjS6TMaAje$9lM#Ac6|eB29=qy|^DQj`F1prA=y%c)HSFcT(*(Gh=$6H_Di4V8MXf zmX{y<7uS9?b`uQ2QSG|2?Qm+V7(s2H7w32z#A}Osu#PQxWk%6_+ri6IHSd9KyD(G$ z7!q5xXNLgJK;h6thz>;v54gcLZq*HQ~Y`Y z3D~FvCICP}p{3EA|8|sbG$bJYIObw;OM16X$gt&&WS0X5!2{w^Fb+*BYt;+4nU|~^ zU*7tLS`X;I0+uCG$@RwJ9jl_*mf6drq&{R3JH*<@^=-(tp7XZLYpZ?Sd#_R*Cgzfo zHdwBPbccd3DBkA+w_}J<&YY&4*tP5t#3!`?7bRP_-4&0KwtTU{1#woZPF9j+n(0{M zj7GMF?FcXrf`sxe>lDk==Z$AAO>woy3RPR*J8R2bRx9O3=&>F=SiSYd#z2z*UtcC$6TSGV^!c{Cr6iDXdO(q3mD83eA^``O$ocuu@>knEu}H#;3?4Te7V=eb%@<{`PsI z#CrX@XWhA#i@29j^u2<0pq)&Lk;yI9DLGfBJd0G=F2?`B z2-T|j4F?Ua8*g9$5f{J#5zG((L}4=mAR~_TYIR@&BH^R5gbf@92sb;?DF{Lor6C9e zAqrBEgaQzSDM&&A2tt&kApnFSN>UJjLPmfHil6}znQXO2*F5{a?b5y8d+K|>oY&nI z>pcO=CI6{oaq3xp{UqU>KYW~%?qg5OP2BTi@(KFcgSq1B{h@d3x5g`szrJ_U8$iV&s9~rzsqw3bAvVuks4}w)?t@t^t>q}OmCJ_x zti7!m_6G{LpF4|baCe2?lnp!pzKt2GAN#d6udJL=*4tsz%-kFE;l zw6=0&ISk1zRxaZ)R{TGDh5M51{}ncd)<;d|KU4LheIH0cmq6Mx>{(NX_MTm_Nm=Hb zTPjEQuPXYZoP#Gar(0Bs78I&xsz>y`x;Wdsq4`?>zAYY2^d+aazJc?^(_R)tVeeyw ziBfd>H2;or!`D;H{ns#=YLdoDlLb%!0UQx4+l-R?=BiE{>z$xX8e02+3Yu)#_3r(s zT9dt$mxd!QIR)@nMc}asaZL2cOdJjxS)4?DZ-P`v^^77ygPGhw{t6cD{d+uUuJsA0%WpPz&PYP+eo&+n((J!@uAzqj}I_K|Nr$DIj#)H9F<^ z`v@D}qjId;u3Qz1hAL=1`#Y{dYU?^wO3xa7Z>jx}O?;Ea+`NVi3%pAfGPavnal(Bf zf10*!@B8GsHR5UZiQ@DzB~E*AP?$=K8LR3J?FYP3PQEk@IOo+Whg`|OQQY<(ZQ^$k z-7+Q5bFXFPqGUr|_-OgSr#05EM?%p-K;BJ34#hI93exrNbDx(1AoAY1)_J)F-iid? zUn~fAe~)XglG;mOlQKu(Rn0kqCsTDk-#NCjTFc>le@g3!Cvo?wy4q}eil2%mA;1U_ z1Z-sOcR0JjM09>z5n%%<1!TRA$#sEH--`@!YPOwY)PeNTw+rN&{gxWt+qVU2Vz%$a z(wACZRsaUa5)g0(7x@Ythsp%fj-h&Ne_ zO{`tI6B$fLw%c?6arEy32R)yfo8vO-F>Tj_{ydLOy;OK)=#f(V!IETL(dsf9#3_i) z*4ggus0B3t@;}@@5B$lN?Y-Z0>@gk}KKwWVGTww}OrDK-YfDRt>T5D6uEGL12l~C~ zpVI!pIZ1UV08nAj-q^z9m>F?3)A_j~fn?&Tnyq@JzW{UT2Ych;S2w{QBxs^1j-oiu zO=_A&!>obrAA?!d$QFt~OAmz`GMC4xZ-m{qUYy6prg|BRNHo1|J#q`_%!>#T{}I}Q z?3n&%wTBq^2XpD4FRh{0$2Tco>HCa}uug|()>3U?Jvp~L{sK7fzPmp#mB)YWjl}hQ zIuN%#G*w`6f80wG$t=EaAQ_y6g6nN4(=jqJwNe!bmiK)=Gae2ZuU3Gg1^8#Q7N@yz z+s5XV^OBg3_4KZAHir(nXk;q(uHb#3c`IekQA(Y$TrSEnU%r+A2=h^+DWzj@2yN+u zd@_ZmPN^OiQDSHHvb{jVb& zXHbEN-9Tsxu>Vh&?4;e^duJf{t46WXo0F;jg7?|8NvhGbVBn=I)ACsd=0cQ)Cb#>Z`Gd=_# zBj{H{Bnja3SZa9|Cp7jrZVR#_h+8=QH^|=jG*4a!RH@)h(0Cgk}8`?e~fl zt6^4{?R~QnKe%8o7H=?((G(jk)IaeU&t`Nzj4wi_5c9i$|EN74_M?;9Fx?89oteVn zv_w#?QNIwlFwq*}z_5*K`F&7z1_0|Fpt=j+%yo%&mP{|_a_+bV=;_0GO8HX^H;)47 zJe3&oUu!z`vLV(kiap5#`w{mcYo}B`gpWwO$*bfA3S+`0u=|F(I_Fa#9HFN?;l~<$ zsmSfGMt%>jRrhbG>o`}P&h80S(w1tuRuKg-{Kxy$p-cA^n}z@c5L@0zzj{?6B_xaG z2b(*$X|7ayBDc<}D6cE{b6vYCV7Fn0IZ+YP6#Q-ILO6?q0kglyM=Cc(xE~|3J+CGQ zE>n<3y8nqJD^1wSjqV#baWlBh;7AAkv!l>w0D%DLn5qkAuEdC-9C8d7ywKK0SUH@` zXU`eD-gm~j3bhAoY+d>B8xIz-8#49X4p%Ngs&>_^#)2<*N8{tLq4-7IOFrn#^^TvX z?NwVlqYQAj1M1{4bFXk^;x0wOcYfF)+~)&4%$aoSzyKS$VZGB>@`5#q4-3bc`NZXe z`>;O300IGORb{Rketds{6ivQ8+~>%2duVNcx^BzTstxOAk^ypHM;zTpSaHR;ICW_l zNSsit8Md_N7MTrU1Rklqo(iRus*&HG3XkvH%eA;SAl$HyAg)BWtp{EBb_OeQzOw57 z^5ew)MNK=&{#7==h{@YyY(!#Qg#Vr`ngH&%2Jn;d5cR(1M9Et{fPw-bHf}&>Z$0Ksb4ApcEWT3y>w9Usn zC*AfUFy#Oy)0$>|!+(Hq?+w8Cl%rmWb4b1GaxZ~T-Sh+ueK*CzmvsPOz+*fU`EuPM zx!v|kS4dA(uTx_98p?NVQ{9+$)JH?o)3$fCcq~=z3CApa?=)tGQKvb1VT})R80h+E zQ-$VVi7Ay+R_?JGe()*(F@bNAu*@`pq(mO}C*MyszB8YzOAW&{rMpf{WG6zZYLDlb z$!@bl^s|7;Kqb4Tz)x?j=^Z^4VnE5|i8)Qq^=C$*0Sj2XGRh-QkC` zVy~!+-&OA+F{YBL4fPyHv`?Z^LjD(334n|%MB*a`(0W~|AGPz2_${12hTN{|p`cv( z)*_lk}TvX;ut|y|q=wa=fC9V6Vb| zFVZa;e?lr{$OPsR#B6Xb7^5xY&c?gtxobJjgQo~!W$(;=AbB)1oLsP|xGG7C?g0Q> zK%~D}3bVtg?4x*mO2wI1IFU6r$i%$rVEXdJtEd&Kj%TfoX(=EX{T<|)Yck8eDQ-Jz zF1mi}Q_%agF7*1sAM2ab{qekznKzS9^;~jK&5xQBHOMP@>tM2D#|?vyBd4G?7~kD= z07Q5-b2NIIm&-&Kp>2h(tM!;*03t2otbhO`ZcEL-uYCfEwlJ9sL0qA^92SGleYrjz zl%hK;R1{I#$@8ST^3Si*^#mq_9xK{=JKC4tU%b(ooBmDS(+k}hU9`|l_&D!L9i|0Q zyflR-d7um(4xB5G#`FrBugiK;8EP8BK7t4~b$wdG&d2#)$X2YT`WXm*@3Y$FH^T64 z%^?Hn0@CLMMlPxS)XIpy(lho8N6(+fAP7@yA#*3g1RH%R5+62r6@oJSK zoMeCG>Z$MEJaG2CsmC~G-|ARu0OxH`YDepOaHU0;P`LUa4#;0kzD^cffF<&ezr%A0 zm6Cj)7~BbS$m6=iTiiqumb9Gj1#r*j!=NrSlrp>vs`)7MUcXWya79CL?E-{NrJMk& zD)oUz7Ayr`%5{mLqODVc>B@4T{EX2uJ+wQS_2cx1)U@;FC9BtUosjRF|!P?|q4LNujbXQlt_RFe}Uy2tPN?SP3wFqHVyEk{P$NF|E* zjCjd^rpFbT^N;sf^KxvZxG1Ehi_98+9fSq++*(a{dB?JIaO00{1?E7Fj_d+@z4Z4e zJM_f}ZqT*bROox)as-frpJphVGiA|wM?nJ_kLGk#c#U6gTPK}67(0p+^kTlPo-&;Y z1lp1ZGYkL>*e+MMty;QJH!L~y|2j?8>TxcoXYOv8h+u15euBQEt;3O^R{_lt3m)L2 zA%fpKI#I=c$yaC)kDuzJ{X&zLT@C|HH1rTg&~(N2EjCf{(?E!PH0L61?+;l&``vx< z5cTx{{Ofvc{80Gpj-9cm`sMq5rNBPYE={dBE2D@&7NLZ2$5Hi-*D}N&#$Z`sV|2Y% zJ!6h0m=hgXl3Lu$JL!o0#*x1-uf7=4Ix6*NljZPldI-k)+85~_P6!GuU*3;+|GOSG#qw39^{IK{9Yd_Tug!l`Bn+4`0x^QS3XU{Aj5oETPd4G`S&lbacoKhmege7!kpXQPnHji(GB@$q zXS)AKi~&%w)@MBzKeG?S(a;B{tdiCfb(E(=7%Kld<*b0OEu!wHY9BcV`GNx*TjxyyW7p|q`-8}puz_TTDkO4u~lM5J_CD#$=G4)(5xC_Bi)km3Ge~Lc2(CW z#@HAQ9R*@-U?e8{M9U+QU%P*_ni??KRDXa00{ubHty@Y-QLhl!8-&yCh*4MCo=!jA z!c(1=ntd>BeNFk^00Oao8U)7`du@)j7GSi(o98J5oj5c$>b9ybUC>WS{8J6_u_H@Q zJZiFZKAq)fsLB-B$_NDUKF9B5sfwj0YsFN!;s9jj#`iJIZBUk(n3p=}dA4=4lL^SYg_e2rjSZn4>y#%6Y2I!16SlhKCRx4Dl@QxZdO|fV z7fX@!HEAcRWY$9{p8aYh=6tM=l&VB2AM}^@sO;DZ)PHd;RMlc z-l}(b0_>l=PO5QG71hzl+>6)>kOBtQQI;i980i*DVLy9pfcbvb>!cPQGUm`v75KtQ%6CWBilAnKkw4c0#uvnQ$oSPy@*p(U(KjgYuP@BthF*h}_754I)IDlxEEFuAE|Mbk`!*3zTwqBAf zu(@sQ`Mb$f`aXw0Ek(^5zk~8Wz9qqqVtm8Ja>VTwqrOt#Yu=cB?7#Xxb@XJqck

a0;n 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

6JWD?;9iE!ZMCGl7d^BiIiKJ0-$ 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

>G2SmD8Eq_ZUi4pum_arSJ^+y)8<6*N zAz#>oH>3TWyN`GQ6YhpCLR)qMsgOid|EHu;&21#a}nS#;yTKm{-$$h5Nszjl_QJH%}BR&*&bSRUl17d>%OVk}3 zcgcCXK`Xh?-8OhK_rK{AFE2bq17JTR>0f|lM|)Rfrkwf>?(Lc_MoXS_%oxGU~gyXAqEiI9u!24wmVb+-pV_(p05FG0dKPyv9spC|s!M;LoaN$Iyl6bY_* z%4_KtPq}_y0IdI!B#U=O7c>FNpO_p!umc7M!KZ&@ihQ2|s$kWL3hC4+W74%W;^@yn*dQ@f(KO|5HcgO4@6{{CQe+RnSV6Bm1tGNyHrR6E0lji)Hvlzza zT9j$p$S_L>n7JNIrb=jXATwfCzD}+ z=ZXMeZsJ;Y)w<{9dMB0dB3_kKTNye3@zfGO#JNr4&1z%;JC9ZZ*Yvj zzVKD_%k|ZBe8?5B%`z(poy@S%Nw{9HI1O7F&6bzGVKlnWtXu0cl~5QdU9`xDN)MN@ zLVm?Bbi#QbzGhnxX)~i>P-l`yZa` zgGGUl1Qoq+#!MfS!M(q}s%wA`yPV@uOW2|)-ooxcB>drYa@#}@legp+nABVG)7{Ug za&ZO|H&OFMVCnzc#OYMJKwcERc`MNe&rA}d8l-BMnk;)L$x0=Z_74F`(A{M8&iG$@ z*+kO9(qbo(2;27MTqGwhe6b0+l(FqgahZfeHyoj(za@c{LYRPaqtd(r9;-)r=Ju-{ zgsK0!ycK{yR_{vPUh!*%KfVgZU<9RYg9Zkg^!VG>{K{^*adgpvM(Y0b$lsW=WzAT4 zVGsW!lEMflEfX`id6F6MQSmaE+)`xXOJS33;JPTZ5IiJ|r4Ya2VuA&PFp&>)ZgI*T zEuo2=w+s6*1Fo^)4vxX1{KII`q4 zX9E;y0GNb^b#!k$i!7_A20bP3^)0Q8C=BkM`X%;)gDE2H@^aB0@`~L1* zw8lZH4{!nq4P3qa&m5AKJ^ate01A#U)GdbV0$Xy}@%U5TC0UpWGVjO;et zL?&B5&3t-YZUpQq1Eb;n9|Qhk$Ogt4-z#T)6~s;E)`xp0hl}P=*L~`)e(ypeAuO=59QfH; zpMILTu!!-9S;Pn+K>`w?!@zA_xs7Yq&S>Sb_GB>kN_b8nbXCRFP5!@l01=sBU6bw~ zBpb7e&*pz4#S~+T%tVjYHPtbx+3 z1Zk=rtKjeMy<3+3_4RMh%xPwIy$W7Jv#jn7$)YUOE@Xt{+F>0;YOWPNzgk+P84JK;8 zmvHCr@h$V(Y6qMMDda*RJtqs*Cg!cdz6z&40wGzBdqu)H`HN@8k#7q=d$PsrintNq zS|j7xbLZO*33I3A6H<7he^|H)u?hra|h>sDZ#2u`1$i$y;Qw}P zeP(?d4Ya=UWb*$Q`j-;&CLnIeiczWWf5D@yzy&Peb@?fZBd0@K~1 zdaZo9U7t`lxz>vm+wA<@DH~?R=Qz9O;X$`amb6flpj3pM=0wYqgDU($NEpF-Ql%P? z&&AX0<+1Jn`WGMHzDiG`k{BG|z&2ObuwfxHYOG$yupDi1{C>?Wzcy9yUN-BIxv|kh zmx=%lm@EAvvW`1+Zjrr)BW;)&rqZ!KokAx zjtS5BBa8BwwnnEFE3JeGTL-I8GYDQ8`S1I04kj~@hqJ$IBl8?2F3GA_Fav!#XFy| zMkw>1n8)Og!e6X*rShN3N0Hd0lmmXKXQ?T#{gm^mND&bD1thgbCH6*kt8lqE7`wpz zEXFxj&i)op_9J~DFEs#Z@ff^Q_YdOwy)J0 zEdB1B#YQ!ndIX2^Y{uFO=n^l?`}#ANeTp9MhT)%jw*1+Qf)7{b?HtI{+T`)Hp?#wj~`8FOC8^cX*ae8EgDi*qS(mx4u(=$U)RF|maSGZV|K30N0 z(r*y3HrBbNZ|Vy{KmLiAOn?|Qo{UbapW;Kv_lL9LD5lRPjsH424#QFQ&4-BxPs!ia zVDow76n}?yl?}}vKw(ROAr8H1qU8K+>c33v(mqtM&R&UJ3tltmvW&3E1X2r$Y+5V&@~BSZAJickJXMrcKN@{ZgE>sM7X)?Bl+uS0a{!6edY5 z`xee0IT&o6OxA=N#+N|4S{qIEO!-XnGw$33LCCMVPqxLh1Ve%faU0Zwf3bgeIEhz~hj3q7=d1dE(^fCwW<7Iu zAK?gt8Zz!vgJ?_U&)hjA7bHwl0@EG_3aG0St?HMIjd@5M0=rI5-Yxq=;Fq*5|7wc1 zuK$?(dr@9hU-q0lnImKu*Ya=vkziD{N@AiFSiO^KZig1G1pg5K28_bhINE6L4D_KQ zIUd1Vtun%}-h_kc$#jN}@5*e0aO@y}&9OG&%oq?rahg!}kyo^)HOQNO+xt;mD&!4d zF)J;Owoog!{QAKXSa3FSn^5+i1s?yJ8v^PTaG|^R!l1ww&*nKKew9Dzp^k7#GducC z87kB_2l}^fCP%gie}DTwPH&(D^i6t%tfOrn9x_jmpxF<8to`5j)ZjGQwe;`O|D%@Q zmfaN1!OP1^sR3*>@aZjw8IRPb!zYw8!5y%z%!XtD=Ts5kkN4(?#Ry<0YXiVAJ1MZF z)qhBBy$}H|CDohn6M)44z79ISBSxyZ5A9c<3ZlI~FTh>D(+v;juh?3aIb4v@KoYam zPzU`?WfoZnW;aZPE&I%F^p+d9#UY8`WoSSxn)y%cWT!tpbfYfXQ71MJZSf!FPT-mW zTn=y@;W!n%Y~9-g*VsWxH5=Y524bpe7@O_JOKcPMcj-<6Df2;Uuad8>Zs7^#8fjy5 zxW`aO|B6o6{%+Oz4B#|wP3)fY7-%vWID(0*HE@!<@kv&?A`!!ga6P*4?|*1A>bV?j zx_Au_dGA~6`$jM}^#m2HFe6CK$X-wQP|kieZ-qTiIM3h+AX>pjrX4pWKs0h2rp5?8 z%0s~^Yt5yiB8}?AT`51@&FwH19nXEEi_=%Vwm#R{&|7R)w~ish>qXR@L+jZqxqc|- zyMiG8XS19{I~x6jE_#KvuTK$0;F@#hx;+4hc7O%T5s+KwTP>))&h}DT?Uu~dV>Wnw ze}}rSI0K23AwYC7uA424k$zAF`jKOuj~A?>?VJ6Q^~TWWdr-b#1gf=F6n?aw{|Se0 z@Vwo*9QWJm{XB>Dtf}TUnCjcRET#jj>z_n0Vj;fRSx*Q}F2Fb@L9YF# zHuB0kc<9#A?~7yfG}W=zvL$rwVapo`lIyAt_X z9jvHJeB1|D&;T>w)_#s@ke?`1o;8KewB9+)&nAK`-LvgQD2jnmy+!d&yRKk6jwPud z`teYAAP~pKlEiAjcE25E=gYez+6)N+0)ymE7MO^+Mj-{2F)~zmi}<%kDP`VFl>?uE zXZ!%cfPZYk;`5zzBn1A)>bqg^i7KJ|U9gQ84e&H0)!W*TJFN%zDu}cOpE>O3Vo#)V z)^$u8K1lrh4~WhUP}Q3cr%`^bb*&x}c~30aHCW89pe%M9 z-Tthf%r|%4)~)Kq0)v}V0wW0c zZ6+V~d^`XEX6pG)UTO|;hd1Zwq%jp^6OY;uBo#3A;u#rx0tg~>dZ3*}w|?@bXK`AR z(u0Dubi(BjdK2HvFV z8>UJ$ZQMFKb$O@er;*`{)3n-?Sjr{t*}Nj_R96AM{D?-IOGvK4rA0R6uj;@n*CQ>;{~ z1)^N396TIy@Wt!OLC@|Zo&BE)Er1|_JVmMz14!Ie+OM=Z^Ev0nz}!u z?{}T|TcUTj60O&P{^nQ^81&XB!NmJuO>ZL;{=!7dkAydmQTxlc1$k&-x8;RuGRpCl zelqiaK8JXKaaJQk+b%?Hzx867)kAgEVmak6S#~M;pS0czg$yr5SFV(zlW6~@{gxt! z?IR{kwI9Dc0f1Gx=_B9|dtmqxy8(G#jkf_|x$pDk0DVznZYQ!;rglOt^kP=DtLSiC zyt^&((QULfV^nls@;?PX7j5xC8O-s6C5-A1+yda{5tq5yVBB|zn3%2JqGmH1kFUA% zGpQ||{E4y*eT&1^*n>JyggiHy_vfB8_n$w3Wktrm9ph+mW89;kHMsGJ3z>>fGQ#pl z-y9#usG@}pbIxG1I7L07vNi_LIquGxmXb)!B*phh%q@y$N;&|nTwnSbii5|D_yY#nbJmcuo z7E2jBEzqyhbc0JVzh0=`by_R={qlQ!_M6hO(bBY<2*0u0yh{lC3@XqB5FfmYkR*ZS z{fT>f?KJB`*T~0HDq>iFB)|Z^qiaIuZ-)!7TFWOL#Q+)4SR|`|d|d~HZZ)eh?j;|M zio~B|uxB`4v+Z7GnEg6dH7{f{_!Ob~xc+`t*a@%LKhl7RY%@>Xlr226#8$5n=zAnu zZki}eHRDHy#TfOR&OB%DVQO~X`1hEqi-3HmsxoA%Q#n7(#7=q z#C?krZ3_4Er99~-5+5NE(!~PiBcL4+v4PMRw3I^j={S$JH5rfdP)#BKbd|`Lp9CdT zscdI0LFJZM?O`}(Ub!Cmb%H}B>$HG;Q6=k!`zRO{w2#wH{Rm)GOJSazk1R&;@A=2( z?J%mZWN{;JATkBwY&W7Yp-~y%+C!w~e*ZJLuVc}9->mcpaq6~A=PW|9Ly%zt>)P}h z8mn5l9u}{l+ z)XoB1+~yxzk7ra~Sv43>RvHhgyW)W|@7mm!IIHD8q;i^rFkA@CK{ zFW9N+7#C*C%?GF)jQVQcUX7sS7Saf%9yq~}$0{X~MK%oOXvsnl)2Ysr!(lYxGJ(G4 z!$l?_#I@jk*%xtNzX~9HF_Tda14KM=003j=(@B`YEBpJSPw(UrenyhsE1N`p$RMaL zcHHGZW#)FFM$|B6{B|18TGGhA+p#c|;TFrCX%W3|*7V@6n>AWUVNvWUx|jV7yzEaB z3-tW!o)694C*HKEKwfclICwq)OTmCFBVUB{n!Wc+2aQKEM9p|v2l0~h3IE>)s((pr zgB2~``=oirT;mb`x3$YIt2e~L?kb}F3!=SuPFSi4Vd#h@q0u}fvbNzTIkgLHX9kqF z4c|ah&;z4PG~smlk<U=kUUnToEi@9+>o1Oa0 zO;Km0>r%Yxfx(6|_80Yun4x&64|)nA8KQbaD)5K0iVvB4*7#*u3-b0;hJvu#ZWrGI zKV6j(_)P3q$|A-e$D?WDf_C#rvac0nNNby5S3o+3R?<**fz^oUawsIjzMM(E^8<el@^pAq`35>GoE-t(E@= zRAO8C2xvhSrk`R-q_ZG4cM#M9bXnYyG;c+hqrl;McHyKfjF@8FO|*kTT)iIL+9fi^ zTweB(G@yV#bRW1+y~Gd(#Qnqrs9+@CC+Fe2?iB2%czCHD=45BRYB@Q0Y>XlamMZSV zPa1URyY)EMf&v*@8Zw@gK|W5Q^PMm8G1mcBF3njtO`(oOMZfL|N`%W7fxo7yHcxuzqo*AUxpwH7gndT6)F13Sy@^}(9Svqz!k``t-k9G zRxS_ncfHlG?zS#hk$=6mj?;rc1tFLt{D?nzw}F^(o!YKyOC~gh1m4Zu!L`~AeGeYp zA%C+nOmJ8;pB5C0f0}w2kOrbG97gydaR9w>)-iD^$37AX1Leg{sNC(hd0W0+5w3#6 ziMNPP?-}Q3)%zpt+`^|5;DHosfMIKJdLXnItPi=RF)@?7V{*mx86$Wk$_i+1(zdDg z#a#sf&^p2HlMcR((3rv2{{U9Gdkvh2px#c?!ps} zafG#2@Cg0R=T8_n<+DG7k-#sDs&|Qu0hlEkUWr_dH_D@%ka;v~8~I|PCXbvdwczqUL)b;Mz9-YL+_ zs{}-V+Y2h|IhE&Glj+#tICd?fIDBVq!E_QejBL<+7NjiAlT8Y#BY`^u9ww97pKLx$ zNPv`ym?fVtQT8w%-E8%;(--!zf0O!ufdT>lHkcuFZ3odf4d|e3rzEK%dn+o3>EZf$ z2Uoo%B}|$Qk((U}-GuL)yU*FY?Bk!vtLw(@V>n|SokuLBYws8cyoKTt)I-AIFjgof zaO_d%w7dV3FgJEYaJCoam&reCNYg5vM{1D+O%gGHS7j-rC5Zh;61*M{Xe)DcIkof| zaX0?e;_*QtiBVYqfdH*tirMb_cH~mfv_#c8s}CqTAAL07Uf+$nqq6Oq_r1&Ed5NcN zFA8Sk8^uZB>zc1uzadkH3>)+m;}TM!0tN$hQN1`fiOH;WaMrn&#Cf0qP0enk!1^`m zzl|ZDpBLrTV>w@4uGO(S1=r}U`(72%H2gc>E zl>0P5T*LVF_s6XJnIQhZ(@9@-YGwBDW{A)9y%$xh?1{|War`_rHs;g-C($ddNh>vQ zJDGLy`LOWSLKx-nqT&y1>G=QFseiQp5aTe7v;-wZNNKo?yBrHyYmL&l0V8;-+lRBK zo*13f(u|9?Yl62&wMFZCutYxHj~X>~F;J=g5yj+>k_^0)6YFpQ&s41hceIFe_L29C zl?6kB9AX;_qC3Kgv!Qt~q7Y^2Y@!N1GipxdT2Z2sOw4zD7jhsE#Og0Ac{MLniK3>cUL9@bGI~ zd}bSHyXcyvFWk;ahoCUqY~>oe{rk|VAq(apQI(uADZfw|xnx?VeIBwG@)A-XRpsSd z%t;R+^0!$RIo%f|9Cr>SQmyJ%fbX;?2wF&twV+#wh&cPAFjPf8w&wNrFgtMAaxQjY zH_~HlW#%~>DM7ti2_dKifGrr$e`rm~c_N7s1KErLTg(XJ?=g8-iy9P{u)?`v7@gLQ{r(moV#fl~ib^)mNT*l$?TMANN^Yqn#zV5})u;OReFR!P z6DZZfux@&mN)H>i+8)Obr*#=oQn}LK{qsqlmSE)qSOiwL8xxq@JO|g`WG+swS>HV9 z*FXKv0A|2|8Ca!Ut2z#fg|^1*s1~6NL87gA+09Ly@FJa8Q!kvG4>y4w4diHl{r{7J zRxH@eF3VA=LQ#jK8Z||LEJ|4ZqMPLo7ut3n?r|I+-h4c=N?oPVBH z&471Mr>A}Tdl&(O0MjjdIENpCQ0oXqyE=&9`YpY~aII*_4-k7GCr3!ysAe9zgicwH z_9YO2a4GD>5JmRYw;!&EA@d(u)CcZ)gCdMgCUEff`elb}b+)^1wnJ-BUU8{e{J6?b z{u3TbypeU;y22EDQYzhalxEYeq9bSxnWePa;*md=y?C@wq>e~*ChgA z3=O&LpD*`OK^|)17Cl39#}!UIUKyWIsG5Lm3FI=1$Eao?H^LV`4`on1XZw`vPMYmu zJY>snmU;PmdC#~~fdFsF?9;>Oz}>)>y)HukiJdmG?G5m_9+1GS`fcC}6x``fjO9R= z>NH@9YmRe}E9N#1QhFd6bzgs_iYs3uFVDvmkj|C2Xp6kPh%_HywBYc0Y>|!KNZMC$ zN+A0szIUb29()9~;ZJM4%l-thdN4B3S%QGX+aVP2ux|Jj2hbY6?l~qJY_?EKdJ#E= zZKBRFS;h&9@F=?s#AarH_knv^?czDs(sK<$0dRrH`-%)#e)H(Bs^7Kn3?bAT>A@8x zZk}~z8d|aq`u=-wpobad(Y2^GvF9`Z2(UKg-YQjk^b0Qv$*JZ;K=9hYEaP>#{yEV5 z5;Diqt2Cu<_CWJ{E>s3=);=%~HvnZs@tQ=XTA(HEqY?3WTaf_}ZQIrDFJHSl+%mi% z0Ppa*M)|OlO`#roEb;C$#Fx&M)?tyW@pK=9AP@!QT>{Zze(Mx)dD^>{QNkd=Zzg7M z9mx%aQeoq;4k}N8y%~q*PbP1(uH^EZLwa+BmRt}jzj@sMktcvfO|LlfJd7oSf6&&& z`IVX7luDxM?l)0hoOiX~_iCYRuT2*%H&maZiRE6LX8hd*b9ayPetx9?WL{m{`eeFW zu~9jS6^_DyMqL>&bx&gaFR|m<1IhTvX_Y^EGKDaYWae*^{;A$5#?{6Nd)U0nv#4^E z-^I9j66>B{Nt5}dPqQFTdp}2tq~GX$DI>sp1Ote={Ei+*TACjQH4k5+0KiG&iJbl! za=92c+x*L=D(jB30Tvl?=#G3vK}cwT(_n1p*!J%A14Xc=jCRhqvflL?NHGI}V)GX? z-8G)OtLV|K;ec10!G)F;oK=?H=ojgzw=fMcZ;$%am{x3S=zNe)E(DF{_ieIHO2OTs zlz-^JW|oG*G{eIYSDta4r^h8){n7`D4r%1)?<){=^a>L&5GXWkGOy`S_~;Et@}@6g zpJ<{Fe0=0K9*JSReTpbwoN(sx{`$?qOg-zs@dvlTKXmVk$~Hj>7yt!K_T9r#S@qdX z<|95RWiCqypln{ML4cAZdT4}@bPYZ&00s;Rj}eNDzxP`OZB&sDw14j~zG#kdZAB~H z{iM2Bji^5FNJTsajp#fZIy2*#^^P#SFx5MQfn?n(%k<(dm(S-igTcFIUO39DVC{!3 zt#o%z08D~zMxRvvoW-A#iaj%k?__XVaL2shLobT5WfDAo==bZ{XFx8lSM&#bfv^fH z|M;N5CM?z9qiBqQM>z49UrUHXMltB3W;b;QiN06QJ99c!1Pnc3_~gJYB{@nbZvC0-@aU|@DBhcf^q*qbX7;9v^|(3Ss;RLe?SMMdS;3S-{yJkS9{ zR!E7P&;^g z!gHiBHVdb_TqE?|gZnpc7C){ZwZUh=h0{MbOS>PkeZk+O=8HK?&Jh`<4c7myXUpC- z5l^lEiRs0BUm(D+e{;mNb=mzYRoYr9w;TgY>`Qnd_R1@1v0tfPFt|kK*h$YL)DZSf zGUj$NEp?w8YxLuw6Uusc`^Bpym9(@I?j0vCv=6I^d}zq#kPuLU4>yTCH%bu+NA<7K zK5(L0(W#EGViQa0RrU(~#n2c{TykrI-5PW_5W}nr87|!<3-yJS+-K)Q^igdEx*T{jEYo-wdTkEIc=^c)|U(9$KZH=_H_NiWYmHLUzSlg zt%ID3I-;=EHu`VPwwD!^6Piza8})V9LV8-yIy7z`@MqeZLpM%K*V|cW+-5HU{ zSoYOIOr@5&`HD;~ynG^2UcK_qr~g^`El1yFIOuzGZGV2RSvav8RKI4MBH?KJQFJ^zYP)(h3QI4f0&KOI|L?g7UHM&ztO?zbTPHWyrGn!JI8T=Ii91J*Fh9BB4r~%l_R5&)@$9)#D(C$I|GZQZEb$W zZf9aGzO~Iz#UIE9-J}GI+$RX#KytjO5_Y)dan77YMGAGm0xC^~_eV&5YCvVuD9H{> zgXxx2(~8^lA_NdMx-zoIJi~drIF>EBSet-_S{5+Lc)WG$8CBKuCP zl4jZ}-mUujGL(5lK1z%IG+}x)b;snDcy!hSycW@ZGe9mV2aw8ldUO^MNaGDCALCh4457UsTHf3#2U+`NHZOg=$jBm!0;-$ssm#LR-uUUP^ zEP!ZS0eSm=riCgPF~tI&j9}{u0EiL6@{l<$aGoKw&XPnEneBVrl-*18i`&km*3ZNu zsTJ1(uzh$?2YOiEr>u|#ipSk|Na1*eI(H1?>pk_iXD|?^01>kuuc)EWcjB+cf2(CZ zDE-r18=?vfbB^Q}#sW6$MrdxgpUr?lIPuw;65#UV>7OzV$vv3@8Gd zO!lmVr1P4A9zAJ9p;rL_oK4Kjt+yB;AAJJe{|P9^o@tHck9p#Du+6JFWsL;b#Dj_) z+VL{MF1O5U&L4X<`NeTo>&=OS$7uPWw}*ZY(9=$CaL2%udZFsW0CdeE{-zUl$qttw z!o7Uka*`ng95M)AzDnZA#2U_ZZw=#m9lKBgdw>xkNBE9Cc-zIp`|CwO*VpP9_+dvz_0@U*==x*lZ#h_8$ zyJ?kH=!^(GD&8sC&2g*xWm@FCza!}h)aib>5>B2>?!9k=D##(uy35lu2Rd_FJYO$iGK5yIRjV^*EL#H3&r0 zUD8LeJZjfeO|ZaD?foCe1^y-PFx_5R{A+~_S$*hFp04MRR%mJY^;>n6pG%9e9qmk# z!lVAK|6wzhCKnB7>4xUr{GHTMImix3rW~D!9IO-JVA-@XV1INzADc<8c$e*&Kut}) zM{M;iR}=(~@dy!Y^gCXAFYI5Bq(%J3vY#--0LiO-&UzIve(vr?iEiMX zAA`;cA;{jVdisc#!!e%l1_%Qx@me%LBgl~;AP8VN8jE(jYMW=~zXM^6gx62rWhvp8 zUE1Z1WhKcrv#-F38#cA(e)X1KK^mb5kO6M}WzhW-JWST&6eoKfyZf>C?*Bx16FoMXtcX^8xbkHTh=i^ z=|DmWUl7mXY&f-HfJ~IVu^A6MP*KmVDlK!w1?)^;Wd?L7Li~aN zH$(}Fux5D{!LO@ap}y~VXN4~a)oO`PDX-47y{DZh)jF-*o|-J0sWWbwyP^!Ag76UA zA6___AIuW(cCNeJpVw3YW2jp3ftsBAGg?pblz8L_ca?YtC>3yRXRjt|(yhKQu*SfA z`^-BpWiQ_^Chxsj)DZ>U%PQ?7hFy4a$=~g`Dz;^NR_eLRask5g#1G;z6t`d5K>%RD z6wk3zNg(;Zd3<%nRMJL7sIjRs>OaWrjc~U=@1YI%!cw)TOh{qAKqvM1?b zQ%(m&r+A_8r73x7o7<=TvhBZfx|mGWl<{u$sK+aZ6i-5`smy}CUu^B>dSTW{kiU;g z!>n`xRg}TfDJGne|H8pjlE_Za8vpb+86=eOkUHd1nZe6X2$rEZG!hsM+Rq{Z3635# z3cr6{|HsRH{%TeUB0>0vA2jg)-%!u$vx<4eLw)L72@bU6{Qvt?mivq^b8SnT|2po# z*~Q+P@@lV%_>1_=imvJgE15GVhrKkR8m!JkadSnkT+fjxWI0t8oIj`UYBK7_{3xh7 zqnG>Xd<@%E{ohW%1r3$=bnerkLUedC?dcU8>!AAo3pdc2NyhZ?r6F2U0aRbIGbu!9 z4mz11vo5f}JnaZ|s9u}wFKGT9sbw-PqEL7N%#QzXw#J!6d(s|zS;H0e8K>-)a~Q%p(lBBW4)d)2!ch`_&Z&*5J>KV2T_RyK%aPw zZ5;be4;L_86+57-2y>l|#ykSn;4+mA@{hC_$)Xc@1~29_`c@U0js`F4gBt#c^7RyW zlP`W;Pdn5S*K=oWp zvGkC(Gf2sn^gbWDMgvU4ej}!BCn8)Fk(RE}U`ab0R?8&C}Wdv!vt%y&V z`z?~)>sH*GNDyf$Bih@R4askU%GTU(_6CDW2Hs>`k9MZ_Cux>Hgv1 zUZho$IW`79A#AP2I~I;|d#n+o^s=Q!@9q(g?&lN3PK(3xlxW8dN)F-d=)Sb?1n!=hCTh%h=MPS6tBrk{`gF zCP?$l*S4TZ<0<#xrXos(wPT>>yEC--3afJJS;-!=%N_ck@TZ-41^b!Y?PcRu#Wv{T z1Q;0*T2S4P!^)^EG&;mdk?K*Rm0C0a@5|-!Vbg1{&EzYWzoW-bSp}NJ+{(3h&uTg; zaD2}T)0Mm9#JrDlrP=oDF`Im8U9GO}rm)VBC%jor3hHz-BBVkH4q*fa16n9T`J?b{ zCHVr=Lp99mIhicN=MPfrm-es}Hw*z&j2_k<|9)R{#Z}|KA0gZAWUMS~cx1q9=`}v% zb2^li!agj3#T6K=Pyp(K>BDonW_cOjq+W*Ck?GO^g4taB{iQkupxJv1h(U_Lf&$etT3+V++-*p78rVX{lB842T3qKhHPx5I`Z|t(S`!5J3EQKd%nJtQd)}kgGx70&6Q0 zLkvU)ay*DT3LPn$Q%$z~vOd;!!N6vpXQy;JyK-1szAn3MCyUu9w!#!1K~F1z**H*K z?LNPbtqb~!W&lBdGU?9pclAFYBKi95lc0cnp=osOFt#ch@>KLDz5a_SO8^DF*dPLG z71nBi+!_NF0C8|C%>EcK9i`i+Z_}8hem2QhBv?=}mlVc4-TTrh@!4y}^MDd`2!5jl zgW(H&1e?`Nw={3e%7!ybPdu@Q8~C^5ogVUHe5)rKME;6oNVJS za2sc?i91`Fm)hUF347&RQ+PvS4@_iEQEe{%&04(bxJE=Lo8fWVy_`ogu#x%L-fu^;LtI!{*ty4w2)O%^dWF&p5-(9{T($_%DU8bbJlD= zJ?&IieC>{>l_wMr6;4x#9Ett#o`u6m>Rwtul~YgJ(HXhOFj5}!zh0|$jRJTdsErN` zy<@OAocDJ1;u(i-@;jx~`OggrEL~QQ$tTtGnh!Y9ExeEh0pgBkq;B<_hGdfhke?op z3O#MCSAW+!Dr#3WMKOP9uW(>~YxJq6R91e!TMf0*INqji@LqQk`&|#!`T!OujPE?s z>>ue-8oN-n;-RXFU3BWZgE0N>h71k`iu%811bbUIt%kk>1@t_mAQ_i&E5tRv-4=$Q zKp}Kr_ZwU~HtsUv3d%p9POZ9{xMMnSVV(VW<+Z3!AOm0$f$9$nZzjnXI=HNx%BT7KQfE}N=hn-&j#p(qgLN;W`VIaUAOdh8K zW7VbbH3Twaib@y=+x8xWbuTEdjb7-@yum1WX^%W#8$T24)n)$^>GVF!PH34v;KxAv zg&ld@xTSy3h+iUL<14Ax;%^N8TqNITl>!H#AXeg9s}W{^DZ7P)~YJeU%u#d8}#AmWK;ZrhZ4`v zPpS4U9VG60G0)y;w68(Bo~&w^x6-m0mS|!w65PD@`RE-LGyKt$o2gt&gk9t-)1E>k zKGz6=s^vz1OTI*0D0Pne?X{S$-*k`1?B^wHL~)caWJFj;)7B5C8ebqkkjA!T$Ck?; zQWn$3IQ=rOiIo`NUKQq0!^|)EAX?Z`8adk4HD%C%`Z5d{*6U{K({x+~Pw)%MNcI9*2^REt$%5E=(dw0(<@{ zbsmCGYSY_-K9D0v4Ht|4l#65Isy zwQrx1e}fKbddahHO2;;LV4-J~f#CK_0-oGp)i8n{X8>RP&D*Apjw)!J3bj9fK7P3@;{fohC3=~pCMAGDeeVfd6sMX;A zM&7&I1IL@FP-5eM(u=KLynKv9E@0&W5eRu&tmC}D1^EZVg79k}?SNgmcgB)sU=%FRF1fbu>k5QmGeStm-5+2wUG zzdyvJP`LL$HWFNq>31J@;sckonl9$HK^K;9qAzR}PER&a2X`aR4u+A(LlwO%-+)&{ zrW(3Zy&q&qu$e7F2o4@hceZlgC_u-A5GkG#`5tTg+x*?>X*ERd;PNxpndh(H&>!>c zS}Fc-D=oOPyQ-YyU1F33A|}L=NImXqgV6bzZ;n2{ka;^www@>YrOl}!$P3>h2?!U# zQjGx9Rs;f36+w*@ISZ&@i9xnl0D%B6hLa9ydSAbpSE>l2pWyU#$jJ)>hk2egmOFCOU>hd*=pqG`S7 zd-hk-MCJL=G2_b|4pXfQ(}%<@;sD}wUX}ROusKDOo z2c~iyBKzs9QX-Ky;IDl`D_4#>y8**F`crzO>^7}k(g9RA1feqGfLwK>yx_;DS=;bBwrnYOp}|HJ$CtX}4>Yxatq=4PnENg%&$ERCCIuy5NHxt|?8Q_k~6T^aEC z{uahl*oOuueo}9YPMjt@F02E(YP_0F-J{fmYd7x zWx$PH*dUUW4+}7zq(GY-!-dJnxo;(ys%Pgf)^%f!Xim}`)H(PTU%%rMkg(EEzDW*E zcv$*8YR9)4NNlJk&&8`hNjl?2b9tQU?U=NZ$(&IDQV<1E0AJ75U%PQ8xf z&B<*4b>pDtkE3V}QmHJE4N6shzihs|LyvT+2?+fnzotmrzQ?~yz8w&7D9uCE{Qq<` zzMd^jd+&SJJ)rI!CexV3#I*)X4ae7%3E)3nD1%y31opYE$@#QsypJ28Ibal=&Aj>i zW035Ub0_>-H@}`I|V^2$S75FIs@_3FGT|wF15DeE;>yRvdIj^1S+fh*l zQv0A^GN(BGG^kUl+=t0?GF#?Y=yCP%9tE%9#DU7P+{pJ|jCd$F9bM1Bv!Wsn#IXH? zkeg7YvrrH~Tu(MPt-~-GzP_Lw@$%*l8uvRG0@oO{OpsTTv0sA76(iB> zQ3(g!wG~4*(L26m&JsrEsVFPn;Gv5`+%k!O5&_!F$5q3T-UAYxF@I}0j_G@kaJ_2R zdcHSzzoLo!%6X~2elTS}JeircqTrNnYsYPt0?}%19jKvb-m_kUX#tKO7)A}6FM#aO zQF=Vd8S+IE_~x+W&5r6cPVQXf39fq;cd=>2zQESC1T}a$QEG^r#4L{hXol6qqbLv%;y~e)n=QV$f1=P2+j7+vcwDO83={XDsVM?FT> z!L7rPY`3xl-3oCKZFv>mIjr`)z03O%PW;3AwCMFq;y5~!Kzu*xFg&2hI4x%5cE7A8 zISBFjfS=NaIwZikN)7q2glK~S4ku1g=8r0w7L@oow<-=5H#5mclIga+FQ@y+Z&^A2 z*%Z{HVG*+U?m@K;!!>#U-uh=i0PV+no>B+lh+|n(t<=P+u z#RKc>)7XK(u8mz*jzawN+)DL{qc(CHDb_&*^e=0-+)QsTmZBui01v6^h0?YdbeJ1k znQDMZ&gsOzzis4v_JLBRo~vS!hsSP&DBq_tztKhuY?{l!1=I8L_BV+WMV zsFa_C`nat?7#+N<54nurzn;8}Qui`v1b+`AW|MDk7nLmzQAq>Q6AaYQC&}iS<}^On z{&!Vzw+XY=>iQZW5$>D}0tGuT0mLYFhpnAX=Ymq|0`5Q0NyyvlAlS-#kUJHV`8ofe zvse$bLuyYzy9d+dJ2?^^` zpF6)v0gtvNU{?CBBRM`FS+aOgZ$lPD`tePAD3Gd|PPxwHsawy0P)KW#J9Q@i+X*n6 zqqUvS%g*WSnCqp($-Q=S{Xo%B=^cm~UUHyM@BRUTRDTL{flPMJA8!nGLS9AkzAK!6 z46~rX=dE-AtwdZ&LrugXKOYfDt)c=5FiH|UX(?x7LdUAMD!!@za9U@ffz_tTEi0hv z=F0Sw=RPr1i~zL27ac{$Wh*uSi}x8hLyuaO9-IXxGyuxXF~)nRU3=` z%lbQi0(c?n2FDysuc9Qtwnd(xVXh!0;7$G++}2+|K0?XpQN8C?B@VYbR_63HDNRy` z`9;JT7k1-iKsGRHV1!1&>IjvPJM(olN}D#UR`q52GZ%t3EAEqY@^1AxpG`H#`x0in zno{;(0c?S%2B?7dYGmrw4MKXn?ek$5GS%2V4N1|*JlCItCi#I@U$siOqowgv7J_*p z0>Jb;RJ!$>0!V-CF2x5op7DO&br#A7L{j1sn znlw|Q9Y9#0CA%j<7nyhf2AUy#v|N(Na=bWL-?*F4Zhy&c_efZ40?TGD8HI}4thrB`_7sa&adMnshH#yrPzEippgutyv7GRX z$H;$Yo0Jyy4aQ7v{it`<0`c{z$#ANUQiI=iCpnV7ea6ixMRrS1IOGvwDOz@<%mph-Tnsc-bBq&vDBrJL3l%m4yJz1M;cNEUqByWOsNNjG<5^Y!K>@cIoMvq=nZ)F?Xb#05ho+sY z61KgeBK_t3kvok1nO>htRU(>pg9f9gJXd%ry1xhj8KSL2n_rrIKcv;x*M9-X8(Gd= zwfe?{vOgbRmG_QAew07Q##R|#tfJ;`qhL>OvsPsK@ukIZkTv5*Um*k9@=$AaC~|{| zw5*J%n$y)0j)q}p+WbT}&UcR>NEm%%(VCpma^cYv_E(eGUNwEaYzKpc=tJ;sP>W2W z;01N&L>533S8lo^V*+d}ux!*TRW?6V_)sbfpKU{j8vWm_8(aRg?ri<7WoU09&-vd- zQi9zKJoUQb=K@3uud}lKLAWoX)@h&0@P7c~@ntPv^Io|!SF}p$%kS4xW+^pK05nxK zKKf@1ji)hxe!~+UOhbZ0!T6LKQ z`;ujNtho@{=tR_p$fc*FG-{nenhK@dHjAUizx(w8ah2d8u&&jNEEN}h6+Ak|ykpb@ zJ*ga>*peST{pxcLv2}7wbhaWdqx{m5d6nhltvuu47z3aD@_x(qYrh+GDsO~(30L9| ze-8FvzTW_mQ}0T53!WhoxktrQ@bK0^$N7m64uC);hvx8P$@jShYf>9s_K>*hwc88LieRVJXw(BAiGT>g@5-6TX z2Kav@q@-{?_XDB~NDI6)48f~OzYeX)-`Oqr@so|$yV}9sU}{ZaP4El-6Vp@d>%^b8 zyQ2`1APzgPxvEpF<9N~lAlM=D6v7DzR*-tBq>Yc)&2djx*Qg77%lnK+Y(q)Gz0K^T zbMI~jo&s?(Yom7u(_okEI-DWLURiR07!rCpjs?yrH%M3N zOKyB|GvroV`7^2NfEP#r2LAtu9pY6hW7lgbw4$rH2wXKD*pRcjU*)#d-zV8OI;8mH zM&VKRj1OXs)`J`Kb&s6)OC4M&!g2c;ZSH>Lvt@r|6*hu{{&)0lmfsh5`c7A6(^Vc^ zPV};-i#BQ~q9Jp-We?q1^2bwnWVw27I=|HfJhQ!eEPvD~xK?vwyC9R-Fyk-j`hg5GaUcadVW{7ar2Gr#|=* zTda}<-EFOh)#(P>v{fo+E-iF-pUh59?dCTfomX3NJ1n9U%Ah~EsF=@n<39hwK7Hso zd@yn*hn)3-Kk=|ql}H@>G7fQ~XYjbFmLqc=hyW!V2FQc{3zNhCJdHe86ay^`ZbT^> zJyH4+7}VB2+8+sAimQ_|G!8Xe(8z;(79lWYuo9D+I~wlt-{%_yHG?xGb~~X!^8GXS z^t3(yZ-41ioQZ8F@AZPg9)P!TAS)zV30aW&b&&fYr%xU<0DMEI#$2J*6q2NZd@f7H1bnE}Rb}T56*qLL9Rl93GU^$qvNX9@TGeE(WU%1y!)| zxd&WPCapmZe|KOLvsI(W;LIKg|K8tht}sE z+TAn#e}YFQW+``u;Giqfy`HUc6@v4-f%?@`R7U1#bix?bu(Zpub1{MUtXXZ*`j}`EkM_d4za$ zW?V<|`1Z}uH(pn$1U^1{4vSM{TEBgwEa$(-kASfq?22%GG7k7q4{WS>9;?yixLb0Y zuN9mdXU!_?-ZBnv0N~H3s_-ua5_;OM9q>fSAfEuf7Vo1(vtwRIV4%&LZdV8VFd%cf z^8OBT`$w#J1mD0^&a~S-06_rw3stM> zlBQq(#?+y2ZQ%(l10_dIySSnaz1kGtIkd-iTm?;|ReuyaC<^Tvs7cLdz0N5k10MpC z_=-@xG^eg2UhrL6lEpdANC*rGV1!zH*@T1Pzw$D4v@q-Bw14P1#Kp{M{36-jB#-2qrFEvq%NXmHU}o%n%xb>Lvc9_t0vLL z3lx_TCIB~|2^M7RA5P|`-mSVjio%akQ5`YXQ)42ly~_J1pvj2`NQ?)3^cGT~!v;yT z_N&~PiwCpO0$yKlX@&(6-DC4BvU2`boeFtdoeOog(&9&2r3?Q(eg`M}e5i|lsoCz6 zp4veor+6boK-{T((T4M@y?v4+6B((+@r$79!VuUTaa25DK?8$>nQ!yx`u1{}n%=&~ zdJ4=?M%HPar zj-ROiXtfz^7XD!bu^;o-ik`EKmJAzpi8KqIw0l_a(HC1XsvP!c8m@D*ja+IKKkG{pgSc3d8B2=};|l1RFRSE7%t#2K|_hx3s_f;$+hO*6Xn>t#^}7?)PUsN)P)ox|J2zy<7q&1^%gXp^~^W zEkla}yLQOB{N4!nz*eNnPDf<|HQdje=QW9{2} z)jYepn)=ENCO{?MH-}|TU|AW^KKTk*9($*-I_no1%a=lz+8fGZk2|(Rm&%b|MX;<& zv|a1h+iKzdm(WZAtnrw*iMyQMh-8)r2JJP6StwUs2~>$YTkjUmQJ+mX3TV7Ac?(1e zVgy1J#;O8_cCV0=#ZK|$^U=cOxG0z^o?i9iN`nnYyXy4owVriE?d>Ydm#E6d$Hg#7 z!vhL}-%%T9K-kX{PwTZ3Dr{xiPgGU5^<@1xtVCH(U;_pR-@9lou=V=sLQccb>-Ssj z`AiOi`Rii##HmdMg>6-fEnXqI+e4l{f8~ew7G;H6o{fSqA3(qtzG}2qB5w+`uPDId zbXr^S!B2cd2j+zC0j(+U)xXr4|8ojV~NS@rJi4{3Xi>;v}tPa&j7|*Z} zJb?ne{^-`E9tP#>^jV#mvm&PVdORFyy$etjYvt)`K>9XU>wSsqH;cw_>KroB%2H$$ zB{3ct6668#KK}b^qqls}*IYK3PTQkd_%dais~@*K%Y992#J3QF2j~F=3hnVh1PQ%^ z23qyjiZ+f2HAQm6Ahq7EBU(iG@$h){{P^}iv>jGDfd^;QvVy&SQ&E7h3WBVF03-hA zshDuOM zEws^yr(0&gp)!vptwn3_zyEy@o*D81X!LID9%<5H!ibSF?oG!yL<*Ad%JWmQOSq$l zJ76%sxwK3RVVPP017lK@2c}Y;T+20*549L)eWvyHQSKK4)u@{-d`3!JN?CQ?Poc_K zs0i_t@!q)kc7g~PAp`|{XX=g@!4y@DL%Z{xUB1vd+%F`u*bfYKR%v|4l&(PoBWZ03BdYl;tR zT2uT-+`ehYK0EHytxf%?Q{M%AU?%Z5o4#P_xu-;+LGLB1>x-+Q;Ry$EKdIB=f!u)m zj<*>DsqXC$1a>=!$xSa7ZwEx-@9{$yPScvZ%H%YHW~xWh@Z%5z)G&PfX{eau)Isd{ zcmPB<-PVrFTeq7t+OMv+ac{^@Y8Rvnbj_k6+X)04WOP*-+V+OQ6_n4b4Acg{qmIoz z;>{;Z>&wvHwFP1T2~-#EJ{k!8d%fK+s|<+1T%_Dsy{)PKO-CmBGaP#J4&+P0gf5>H z(+i*TfC@U9FLjciy1z28GO|}pf9nfczk?A1h)~-w^jo^(KYdZ|k5{?zjF}fGL;CPx z_Iwr}LopG&9`4)k!OrM(-79iKe9%3aG5T?dzuwz9dJ-VpWu{`wel{!ysEW>F|D+Rx z1KJn|mgy9nH7;CHu?sq24K6>=RqeVNvO42MKcDFpucyTbI{=X>3?3crck9VZ{>CCV zs-etkr!Nu5X(?X<7_hsIhLer$^QYeL$H7i<-kShlR^ghm? zvDIS3IRrG}$AlGaQ)Bt{%i5;ps)3L#DJX#^ggPwm>jMohVZ5h zbylgHY|-XD0`qLN6t*Nu`J7Nb^m+L0$XAt;i+eq*4qh)7$hz%c@BEMmojz67a`_X} z+v<$kve}z{M2vU*&fk8^y&lIS!K?e=G9N_h|Ai3@*&=h+@5I^;j-?=F^!k&|aHhV8 z>e=#H8Uz7tvD55!>||eL_Da_${B?otA$)tPaX}k5Uke{Q~(JP zYU3DVu*wkMy$=zCj%GUpeORM#pZ%pe&2EpQ{bNl7(p-=S%y0&HfRPm@>tpIq7rp+w z`0fj%+l!^*EA76NBs8BjeCFNX{3088s>29}t9zutWEvGZ7S8Nudm)P~i%2_?Cng8{ zIO}<}P2kpJ$EQ-vHjP!&4aDU3<5L@I;(NQ(J0b$dp_>7eOOHMv0tg+Xrk>XetXDAV zWnaWvhNF64pify^y@0f&O)MNg^yTj;(#6Pi7A2|ytCmgkJUz~u&ZqRr&~<=xlEVzD zj-E_v%|b>LP4we07`4Ca&@QIT7L66)|110Kx?u42BmVm}VcuTnJ%|AiiGGSzPlmNS*4Xz>y`F$s=&S4T8A&Yyd$(zQ50T6>aNus-TVCzB^_~fdE5= zRGJwqIBUD3*s?v#S=+HCC&V$(9OQDmXZh z7U2KbY(XcljDGS_-d#9e4E)LFy+HSiuAzq!2MnP^LdS9MBaWq%Zm{+LFE=hNPH|^C zTlqa!<-1R=AED(9`s?e6D=iutgb}qR1Z1tcg5ZcM)HmxixEUJJ-7WRz>rHYN9~XRQ z6+(c}-=k_UFo3brgY!1$ZF*mQTTkotB?^}h_($?+z!*3N25;3A?jDu|->z514Ves^ z4A5|iAh1EcvL14jH})<8>_7&0b${-FX1=W|%WW-8R}^X?x}osVifG!7lT;qgIedT%#g1|=gPn+$zp1N?M0hqaWB4Ym{AQ^hoIUDjn zLQCKb15E;PVHAswa04Ks_is^08Q99-d(iqkZ?c3kWH%1D;41GJjG;!kYmyu_dTw-; zVx+#J7L#cZ8@;CQf8H8<4rPbGx@+?HaNan(c+{^rfdIu)LaZEoDzHjFu$8U)CXVot zVUX^pu-RbEkowAX8kl*mtq+yDR>{u~S8rcw*}EoXs%o-wO$Tjn*M;CNSTlAwOodN< z;0Pc$VZ9*@P*J?(X8~1RDk<4>X1Jj5q<|uUER`dOf8uVWujk-qPgJyZPt$ND^*PF> zTlFg3pTO%Mdl5HS=&KndLTDI(H9AFBvTtu!e{_m@RaL+&4|0M}T3V?iQ3_u}L!rr= zQCz#i8wB3-tMouMOzVAH1b3ufYJHrj08_hnKh@kl<{vue<;yeOaDDP19H9``W6B~G zG0pqiB&V0_^#KkqF24;D<(k`X@(MG%(XT3fnJM|Jitmt^j79bxW;pvXJ!m~z>>nyv zRJ*_vrgY)+VAU2iyRm>TA_A}*!`f{G?M1q2Rd+WQI$XZGvUi!wP|7{{94sn-Mjq5$ zBOE9I!6)YKuYI;#8A{B z2s~L_;ce)0#-~w(?;!o1s1k}(UfcO(ij%)h?US9t3;&8MS8kB>yw73P5=16Cq&>jZ zJn7a=11z->BJI;})-L+wLDihVClCR~>l$&-zM1_s)o?UPOQia^NUKHc`*@z|A}_yK zC=UXR^~W7Mf!HPxK*CN_cJ1dumFb-}`lcIX`PHo$r+EMXUb#EvR`;J@k2^BFr7d)( z&>|$PdHw#kfx5qq0ye`_fjU~k`+L>EEQV~jr#!1mUrXG<1~c>pGL8cKKcFN4Fkr^v zm!sAI6(>wV5GA(0A`c!8O118MIP0RgAl zLH%^HJvG%;2yHKJx{0{p6<+X8V1cr?(v73=el?(M>+# zy3ow#k8LacT)*i3idKWmT~m&qa(_*gGcYf)tE+||a4h#9X?>sEi4)(gIt`B^Cf%cSF{%%4xeRj| z1^9Kg4#W^Z{^xMiSl6@%yeUq;a1#_fEDm*!#*g_xabWN2aNCbRDCn(#Ny0Ws`1t!= zos7qYdV)_b?v;GnXD)xUwGzeW^lao<(!e| zF=`nfr2|wa*9kb(!!%IxeFcAiy?@t{ZTeRfAc1y98pX2v-B|i}a#_uN9DVsv1fxXw zuljHJ%NcRm(;GTnUuWT!5DA7%1bW<1f&yDwxywm&fi(g|Qd*3y{7H;yYluKEWuR6v zVw)8JUd93Fq|F3W-oHhOLDBv1W$UPwrsX30U$br~)a!f`6TL`%46GD?ZCCFgf92w~ ztn;Ka`=J2*8hX@$1O|qA-XFmsG@tj!e(f>6_(1~m{B`*q578}MiS$VKtz^W^TvO`L z`N#S_2PS)P|3|Lsxp|2LA$BW&Au@h3d4Ow~WNGb%?RWM4523I0PM|Di9m#zIJ3#~v z_(1^;pYT{HGUKX!pYV4b3edb^OZLajfVD~QG%k-7PLY&VajQqQ%HSITxj{*AMNXd$ z>X^>$;8H@-mEYyWa_QoM@;XNOIAr!N-wk1N9QKWtbmzL}kZFIN6f77_U2(~G#vWl? z5-zFV|dTmp%uQup?r0L4H|$u2&`+5|$AOiziyM;&UR# zwIyQTg!s(+#{_7)J*`R1q6+DD9N6|WMI<6Edv0(`>y%_E;!wTq=7U#CKwI)%)B8aK ziS;o~flKj#{VQC8&VbbUm0xnD0Yg)3O%A;TD?IU&5i|}RBcrmq-^j2JK8T2v*xO!! zk`Ml?1JL04)iNX}FYO}fZzeG4c!1}lBv5qt16#ImTTD)XiHT~%Ixp*gjlrd$B;@E@ zS`HD5A37FV+hbF~W?2vDFp8w8K?D91Bcca*CAXE5Sb+pzWI|v4XO7xmDnDthe0?=+ z&^L}KK?8%K&z-H;06-^K%dfWGt*PvKMyFieI`%w@bS))A+IqP3P&-5*eQ#AhF4z#e z;D0LR-8ajWf%*vx{opXbL%gl^AwK59^MP*qnt&$IaIaXs-EH?5;Mst+gas!1fCf(= zfz{HnwB>o3ca$Oy6ZJgJ zMhX|JA(Cta9B>uhJO(^|6NH+pwqf8G1$uc?nsrxHw#L0W5I~2V>g`jYqmg3hL9JD%MHmFQkm`$!YM7vT1jkYg&BNEi?X4Z%JT1@i4! z+%tDL&Rd?xDG6bj5elnwksa|O4^_}+&bA1HAM4BMFdav{A>YJ7)JzQZTnJUWIWjb~ zM<_RR9Q2F({k;xOg9;&m?B#z6+@E!+6&Fx^huU!eU_bnZikaQYIqm=90d-UzyUtVk zuQQvm{w+&=zwA=a-RAZ89nY>?`0u)$NQhJSHNKoW<@>i7%(v|A@HZ1JwPtA1i*9+BpfFbn$`+2j<|wT-(vJc`vX&+-@cJ=xo(7XGjK+c3!AfX!*s(IrDNNnMKzWZz26TRP_)`u}M^zrV^}NXPRH zD!;`QD^l!oCGoIR=pBNX!39e)c_b5rCo032wLe}@^}fdBZ?ApfO=ZDfNTrnpRL9zalONQ$XBqU-EG!Qt^$xK5rgMxG3~Z!W zRng%Q)1NI%-F(i1hd^Ilm6KVp`a=8HZ<2}z#MLK`$19}!^? zNA=z8-1#8Kz^KFMg7ep@hNt>A#_6Xy7-{&&!7YEruEbw$0=7YtTjA07xb^BY)iREX zjSB9ESyI&$A{|zED=3J4_bcrh4IaDWT(DQH#&iBEWZ!4|eDk?3{0t1Q@&5DIkeK<) zXRP^U0xBt{Yomz~4akUDAhj?TG=ZHBCs{BVER6Pk(OKrVjdPH+F_{w|HY17aj02>{n|5e~}rs6g#RLh99n zSeP^<`t#)u;&3s>NMwJ3(|2ZX`88aJ9)K>%o=5i&=e1k*odR;Tyf8 z&#asK`;Uu6ItUH!9<8FDv4#YVb%xa&7F&R6h4o$$Q&w{4O$!qY(N@i*CY=4dQf>#`RO}AKsY+G_ zauhMIT#rxyjescfdE|DT7^om^6P65LlSq_lLA3>;UhD(%*GT(`ya&?D0(f=eXB|@M z#5N;u4}mtnF)ZpPyz32_-r7cONh_6=CNHDqI_zen)FtpTS40xuktV$IJSxl`K z9J;Sn!WhHKIdd@Ls%5};Trfa^ZdC#vlIo~&c|cT)tPLmu1PxXI*`v8TRdbjBpv)eh zplTkERHkdnbQVl7H#UqfqIjd8uA8z;hG(0|<&f5$y2kJlCSKFtRLQy@(jj$ukq779 z)>N@wv^0C5}sHn<~K#6`6qtf;sf4 zSrV3AaO@jOmJtF5&4Z$3X!9*PH^Vj>hI``&`$w>=_?Qpgj^`9O^K7pVuFTA=n=Rb$ zW}j*jser^e6mWL)%nMmdumf3Re3jBWU&`l3Tc|`o;)ytqm!xN7hddW-pQ}h>v6y(F z1PhAj!2woXt?Ux~P-UKP{wk}h1W(f`Ob4RdSB)`6*iYJ7&g`7d-rOaom&=jHb+5sy z!KNp2GMf~c9{0y7%6x_oX}Yg?nzL#lnI?LFA~3uVR@uGmKqJciy44(nOn)pRl{R{g z(D=|=JRn9BJs4FtmhcH=krZ!jaHOR64cD1QTa_elCdz&>^Me^V%RWm)O-;SQo!#V+)+t+IflQ19Ef3 zOVnTnrlnXofm@&0y`jg7q2~49=G@RLrgE!SN*)|09XF{a4zjXyph+}i>XDnx(w0?R z!p1V?wl1&CGRYqDrnSDx+`iwBVhT2+4r%cQ`0-z=Ne~uEctlg5R=e zsYU+gEvU5{Xa+W z52-JNiYlPuTw0&l99OtlZ|}g#AnQy7&w<_-faw%IjhJyz8nE$UjZ=Y%L1a}j#zpGt zq2S=#NG4NMnB!db_H-21&LYgN-Mh~zyFW2|xjIxF-i(+#uHPYdc>(rgWUJcosPn-K zD~+BCrR{XI%|50%H}JU0Eh6wrS~^7M1VcA`h|VcYSFCzwz5HUUlyz(Swm2u5$pECIUGtVnqtTyvz`gh?4l?DX=Nv_f*dQ3!6o}}5$3Yhx z#PZN~j%RH$RBD ze0b*xP4pr9Ix$|41Wt4+me5Vyww6wsS<7?+O4UQm9dOlMtl-`~5E&{d>DTY?na&*p zj-2SV9Jc71>Wm5C~{d!(>(}Lm|^%+4GX{!xxoAFzzY68irf6 zd?C(g^I%(+(BaeDkiB6C%14C_9nGB-(uBQy%B^rA8CQ5IEkW3c_7CM;pZ>t_m$R<4+~2BGI>{2i&PNCu7wRq@04CUo0n4Ry@iD!#8>22y z(~TpGsIT}r=+Y4@98Sybd3p_tCsk(4XA-`?^rB2uIkvWgaFs4`MZ+{d?6u|YH(JWa zxBRfMJW-BV?}#JMO})Nwe}Bt%KD|A70<~)pVCF*38;>;Ua$kf3;(FH=*zpc9UwgQkh)c??Zybr<%d^BmZ9f5O0jik;^iell*b6!nVppu z4wGrCq0Ux925dmWP{-zpZTAlmJZRwj^PvO{&}qa%FBMrEUM8)hhq>9N!7#Xy+D1r@(%t*#D-pcY;_LATR@>vW-fOgwou1)Bd^oalwE49lVae7Y_T zx?<2lM{La;BiH+WxT<^}9rOKN)^@sMY)V)pXVyb`Vag?aMv%)UDvb0|R~!p9Ss>F=A6bB*d4R^k=1M&C&(ysDMG5F~ z^7W>$H)Pq0O>V>)MtTGYRgt>yo;=&2{$T=)?C5rx`4Djco~DnZn4^GIxcEE5o~pdd z6Z#h$K2UEik>bdbNnq&SkUCfV#}hert@gV<8rp~^uz0+*1@-Hwp^O7H?04sK{M9ZzM;# zs^Q>6`dJGR#V+E}K2yWjEpG5WcW{>R>Hrp(me-U4#qiKH}bI4)_CKHx0V z16)emyl)JNQVsXXR$aVs`q$HP=CgbS2)T=7$PEoTuQepHh;$Btl`1oa5)_!tafSiL z7#3Vi?tmGSXT?fh_SxG*RSjBoz&91>i%4HE4)Zryy zuZIgxlRLx*#2mIA`z?qV2L$PB%yD{%QhNXn1G#>+g&L~_oj2|_v?x^RAsnEq{0^aO zB>>@vD}W>^0%llIv)1S@-&Mj7I2S1Rq~Rmbi5%am2@CYre>${1ay1p~ZU$|DER%8Z za4>Ew^lp1RDx~aEIlB;_tE5Mex!Pr1TEcH^}0KoniWk zTXlD`NmceOx0OwlwyQZQzSttLSMf3Uoh44HWCC81;cojCLXRM-xM)C%?QQTbtjIFB zD~WxCE9{v!Bt)q`1{DBhx}TY9sTrSDB5W&hirq++5@*H_@S80&5HqnitgRmC2(AqZHqF`1_&^;_b&DH&Ji?icPV>&}lby=PabDMm zYx#mLRedKJ&vqvXG~v83X2>MYHSN z_;^{!&hE+wNOeg#ENy>Ynir~HVbQL?(#1BUjcwv6LJta#`Up}wBraL zv#j!M?Az3aETcu70;>`%_Lg;SZIaqcFWv^_5IO%=OOWg$i1DDb?Omzx828134I4 z8+RnoH1`1>>j2)Io4rUeE~~Dq+wNEm09Bw1kxGKPioZ*7p_9xNo>>&|+(JmWYV@z! zyNtzg%C!;C^)!jyZk;yG8yeA53v~b917pP~*xF$Gw~KvGC^6Dip0S5V{7F&6!>#a$ zkgITFDq*$ah}C_za}O>+I#FHA9$QObAXUP_vuc3CElkH~-&l{P<${~a%{wN>om$s` zA;#ik8??YvDBo?pWs2I86gNoXWuLJ*i436`C}{_)`A>N23A&;}=CZ`M6d#qtfnBGA zqTE`efKD#?ry!W)i1?ZJ&1erVcyEdK?poVKGpdh=2!#ZTz!Fe_vTMg@i6pw*3fT!u zv#KCK3h32wjP9`%Z8saLUF0E!dR=>8rJur8!on?fxD#!==S=pnUY#Kh*jxB!j|}3g zPqf*91 zUrMNF5rtx58w8$x$*X1?MTCOmci{>mHhbX{RuvNRf)~eAIY;D98vl#--Qei!$>HREFq`(AC zFLe-E;vB~>6V!EJK1^&Qzj8C^lLOjLtk+S<4~m(XmHn%`r-2V}WCn2NB< z;1BlKv%WdT4qNFYb+Ocd_l}LOa(d1;92@zJUEiJjsq0RJ1_BFJ!FS%@oyq4c zI1oUOYT;@OxDEmV3uy0J0T;U#!LcSvMAel=PLGNUeX2O*^94nbJEAF_{|*mPFMB+b zGaJAcSHrV3nvTeln+O@g=#Xr$f{bwU_cMm=70<@fs@!$Iqwt@2WFS!MEZ4X1Hn0u( zFoFN@Ks&+;88%j9ad)@g5}c}Rv|O#e{Jq{2P60rI0LM79e1vTqbBZhyqSsso`#^%x_mGg`NQSa$3;ilgBB2 zrV3Zza?b-^pNv4dq>IQ$U{#Rdfw%$H)p~HxbbE`S_Bu}Nm-J0q04jGGL!jCrjsUrv zNUA+eDzj@{93_E5UXgwIxPaiZtU_G8+W<9O56ud8^D3v7I+8^?_#}RQDgHL^BUY}$ z^O_n4Bm@;5v9!yZR&M;@GULNGLAd#P>`1Zs87z(^I{b#Z?#6wWNCDc-xGsaw50hX{ z)6)kBOKWXZ)JNz&s-riH!hf5VSG1N2mA(^rM3o$P;8_m0d|Jr$uAbh~b~J@SUyT<_ zpbry>-iR1aq}rJU!0coORIA!CGa~V!QiJ$46rB^J-V%Y030|uoKByppQheMrir){z zh?)kML1b6yl5s=F@Pkc1iAsc5>WZPXxn_wXo-CMF9A5FK@TmA~OX&_d$)cQOYxYL_ z68FckD_#+RYV~1UGgw7q+T-%RyHuPxOaxjBqS#q|5_N(*!dWi>GYo0o(+B0pO7#|$35p*(6 zLo(E*qwg7I2#wSM9qH~@!L^Imxjcz50xFx9!qu6?-o>vw!Ec>h(6;$M-&{H_ftqdi z^KxsBqgc@?O-_P^VG9a53IG{DTx%#co0Eotd1)3I35a{gP&6}t5Ux+ zex%R2muWYlUuC^#ZMf5*>=DM!LdR?U)Poci^Wmo;=l}^oaXGj;3cB?~mBE+moXAF` zt$bKE2S+v8Ca^Sd`2T9t&AY1wT3I6Gr?A7PT9h<_g;-*%r+pC7AY2uVhp^1O(id!T z&pfhbD}eLz62iMEKRUr)pD#EOT#+_<0>n!2_#`iWrD4s~*S~<4bk4918@7T{XjBNvgY!@9M`xdBI=b{%TRY+L{yKF}D`dwa8~5Y^@qs zs{e&<53mc%vG%;#7wpF&O9BobmbqrtB5a@#1Zq1*W2P3$w7aQQ#$6R*alX(Rq8uTh zGI!2JBe6qXNlI+DkF}CCy)@dHCAWK)G=O!7tvADw<_8Sid#vTaO5Zw|qyM4;d`$z0 zdph}9)(ERfvUiCP^P8$k(=cd^g0O6SRSu-y7BYEabTrdOQg&%_4}=gTfGXpT>WbV1 z1DH7WK#XyG5r8B2GEJyOUkz~}T6{NJoG2FRjVAMRn)(*p@Xh<*YN!1r{c(paf4Vnk)3m zkDDE9VhA$|AbKXxo48Ng0Iw?Z*@7_=-rbDfJ$u5J6hw8aP*f)b+&Ur&y0z~}`dQlN z38s|b8V0Cbza>nYWS)9+6eBfCZxy;?>H{_Go7H+HhnXY`YpfQSx*Q*^#0|UadR-n? zNYH`@nNK~ogJ&MS@e&(EJKVT};O47#LBBEQ*WVIO_Nd4>EGz_!(rV(?$`7upYCw7# zLz#f@Pl##l&!kBIG#N^P`u0)|yOt}hz$Y`74dZ?5M7VXT6(0x!jKxG`YNyiB;CF1% zA60kcELoWMihBHXzeK2&!PhEVzjpw7eVwV>)gA4NxSi%S(D5Hd>*wcYU_sv3JA<S_;>SqHG8cA zhX)~pK+NEcGPf9c$xOV`CyVC~kX$m3FCF3z!7Qw({Nv&}%_0G;*j*O6>`d@7utXn; zPbOd*SXo1nMJd-lC4k|<1A2W$upI7El3#w(({s+D06J&rQ>Za6nW&Y104Tgm1trie zh+O(S!K$D$3 zO0Km1cqk2DdUyvB@+puJf6R>vd)lH23yo{a&$k-v6RLu`!Y5?pdW8-Uw+>6 zcnH_eR&q!~@U0PiDP8IdCbg}&AE?EWN3MXs0LP74HtsY%7>%-d{k}pMpgrEk<9mSL zULRKD?Ereq_n?3Vw6;AV>$L#6RjD%miE~7-ErV|&Zb=|q%BO-pW-&4y$vRMA)6 z6Lc)3l-61QQ?y$m`v<#u#XSCw{>pUsZ(VNrmN?*U197c+_)zpEVJSe7t(~Vk&obE+ z3==-CGXQTB<^5X!hjc+*}@(HWD zs%KMF(R#I4rK4^^OiDv<24k)jwsr=tmkB@Fc6ytvfx(!JNM>IX?FuL>xcdBgB*_o^e2rA?h$X&eWuD^XF3dI@~=Y`n*J+T+H27G_!Kshh290DdPLiYZ+FGk8^$@asQ^Y}HL?By_h~=akO*aW$ZrzuU zU`%NBxQCFBo=W2ZFhV*=r0>De8d$TqVe!Cra4Ns*5crug;t&*?vGou^q$<5S`Y1Q- z=JFzc=Yy^X8Iv{kd`1|z)S~ZS?PM!SO`GcOXA?|5y@G_>-T1b&`3y@v93~snJeCPc z4wRk%;nD9Lj_MLT@zyJS&&~Ski`NE#?w69-4%UZ65Dy?cGyNe^dZW00wKP+UhIiTX zkQ>sPSAd4~5-zrqd?lE@Mu3*#(f^2?9t_5WsMi1sSq{)B*V~U#b15`7l{_UtaYcVx{S3~HG{ze|VTab;m$$;|_EO&L zx%x=*;PVIyg^&WwsCDD?VP?k|Mc64Uy8B5J4y^Owt3dLaFMin?B$=~8l#S>f$BaP@ z{`jcp!I3z@e-CFNn7Oj;r_3^&EuM=saNV~EAR)`$*az3G?Qxy6P`fyGD-&w=ACIV^ z2O_jnvapOJp<_UeJqEp<*56Qe0#n6`9@!$2d~-AAM!o<;v@C{L+ODR`>@PBEs0Qq^ z2{6UK>SgyYtUGimu^}Sp&Ik~xwF}qHrwFnJ(ARo9&AJ*kO{%um{p{R>-B3QrUpo zc4gq{=7G-)t5n_si)D8ceSIvJ9Z#F&cTv*+yr=i*Ug)~#7X1%n0751o^Aq)2p$S+ccay4b62Edr(HWd@{aBXhL>x84yhLYclP z{hI5(II?@X4;xC<={H&O9oXl%-sW9Z+r4{$M(5Npcd9qbGdbU*7;UeK87r1);66K(lUUSK&S>=kui>!z1|=Y4*`Kr>PAV!DhWG7Ivc=0 z8+ocYAVs;dz~nfrC;nS#v?`s|O1GJ5F7m3IxUh+3J=B07VQ4^W4np01rG_e;%Vhv4hF}llQgb)-?KMuB@7vp`bT(s5N|9@{mM0=K#0g`v80UinV-oK^ z)59ZyVSNjU!m%A+1xa`AW7bu(&_4!~IR)B{z4-Eds&({7G{-OkvZb3tv+rA-?J&ch zrOj%iR~JvO<$2C2Fosn#QO8olRlZ+!S7PST=MZh=Vn&86lmvWQr=m};fSVr85wL;p1Hug&t-W7VH|Kcj z4UQb;v!SD^j06xIT=O_<4?Ol9__?%C5i`I*YHZRJ=jz!}hf{=+=<_ub4+BD);ZYfh zKu`e(3k4&UC-Hfp>;TH<2f!0PCZbuFRCmB8nLBD}!X^kHONCAJb>UQ#%y6FQL)LI_ zI7Q#!`=-vkKB|-;JU1ib=B=_}62gq95sD(If$aiS5zVTbv+Zidqcx!Y{_;W|mp8#% zO=brqOnBb0Nj04o4wc3=xGLS?zA|MgM6LA!d`3B+lY5OAhv!Rzgq;Vo`8@DaG?+;H zLxl-PmCVn&2q1c+!-v~jYa z30R#!1k^Wk+tw+Mm*B7*2S%>mIU_+C1QA5*4fa?NP8v876#7X*u6dwX7(Z#KlkULr zmM2=)@O2}eEhfHqDmeo7;em9ldnE{RH?IG@UI2J~NnI`ZP7vX8a!)LP zLJgJ8pBEUIcb23duAmS=H2t3fyjS9`}V=?Bj1<9oDe{*?C>zx&=tPK-7q#i zz6MGD;*;T)MgoO%!`gP@`yT92GPmw9AR{i}lmP?@4{}T;qt)j`o=L#>K9v{I=;$Xz zw4T7}Sz~8prq2TtFy)AN#vy~yKX&-4<&GX4d=NlFvY3VEay(?Ll61LJYO+9@@@3is zZnyd1^DQ0YH;dti0_j=S{N5zs7IRd1l&4~oNqlikJDS#WX!P4^_Gp>; z!dAiXpdNrXLD^9Z9R$!V_KQQ`Q>0NvNvXpCPJ|7t`x{FIPrO?F5M|bmu#yVSWS2$n zfX9(@Pc6hNh{cl`$&+}h zpsb*EHPATY9mkP5*7&G0I{9;+^qmtrdd&Fdo%pu(Q3!ztN!!jqDUd6?u+%R^Gb&GN zzLo}F3FY>vDJWQ0wT1wkFd@K|5!u5Ks6oZa5~$H|G!Ju(s;RlhQJ5hBTf|GVMjoII zimfpj-#2Ymgr_>T!2asu>4_9Y2~<5H6YN=l-#0QGj(XsN1LVuKt1c7V=#j{@N`)mY zf7&nvhT{-WsLX9K!YIM*ZveMNISSZcaM(ctkRXBh%X6A8jNj0&Et;UG(w8)C2AVke zVBDRM>|}JQc*tor+$|o1W7w_eh4O~+18L1t+R=A52=FvYcNg$fVnm8?Szrq{Iko>^ z%G+`TMO2{Xvtlg`K_z4f*y4B2x0q!3&L3>|3D zA%PWE_-8mArtpKCC4Fmbi)^w!Ggm0h z^oKJ$+&jVrOyncrhr)dqzhZxG+hdGi>fnEz#VTdk=6rd zbB}X2Y1kf?nfuf&I7h|i1Pb=Y>ii3yTqu!5iJNUpvEd_&pWUruUUiA${r344!x~}U z{{1*A{lDffdvf>sID5!O$qPo(YQ0NKav6*|BfXXJ&#zAfr4+QRht_orBN3`8VgwL9 zQ;y2h>YxOZ3<~RLNxt7cH*=fFopu;Fimeyg3#r(K1gCNSq#ea6{a1}VeVB|+?8LE<_`nQ%{vdp zq>%N__Lgk!>k7gmL`tKvy{rd(ls5_Vyu5Wt?$Kz?+~QmP^Vrllg*pg@b#*SU&+y;Cbqn6hOn+TzjiDV5Fm@ZZud+JtnMJ0i6a@bA@jfzdyJNr7!h z3|K}Nw?$4*x1hVES9s8V)mnm7S#W*d{5C2g9Mln0u`HH?sImta+^sW2GjtbMR3xSd z3}6D9;yOb5{7vR3oMFNKVs5}cpGIOu<2S%vQdb2wTZI?S4A!J9=(3zhdW2nz(d$jh`w#w z)xEypRe71c8GDUSJlD~y+~;>pAJWfi5?I*u{M$W67AGMXW&?_HWrWq3;5eOuZM}t) zsAQ*{X3r3X-xdKYb1e*>DaQHZ}odaal#2^S*X zGM5GJA1N{OmL10(Ph&+**)!O8!}maWqNAR~yR&8?j&Hui%*R62u04tdd(L;kFfU|5}n9)95z-*zMhmv@)yjzsi*4H?vl0x z)((PVAM=Idcm#%aq#|nm_)JV(<`^8$IudB-^YJl z9Wgjpz#`_f-6pqsQ&!eisLWbcjpV^VYV63YZW#2))l&?8ig&7dH?GDo7pv8gcLp)&ZHI8)91=|2%3pk<-O*?JS zRe1?PItU z4^AG2na%5t;b{Qy`h5X)eIFzk`L2+?!;8H5(L}hqa0sEGhf6zkyCp|$L^J|*iPo7>+@_cArX~Yb3LtM$iQw6ivlcECPqn!ptX<1O~qlYO$$OV z3wxO+myuYveQu+n+J2IkD9a%*$X#mJ#irJ~^e9I&vnh*c{-jjB){K`Sk?>O46*3S& zpARHoig>U+UCS;((IFBIK z?`-5=pr6=mToV;2Uw5Um@GbQ4_i0psBp?c*KJdusaiq_;!Q)x+qrcgpq3?yAJbo?9 z>fl~Ciply|Ran?rWzgPJh9;^@{meGD>H9Etowtjq{TtHa)m+;W5gQ{hhC zuCYMui(oxLSIjDG?vQBsBPHvU%6(%N1O~L7ffsv8lpUaI)}|gf*fg(7S>c{m zcLxsQMq?~hsAG-K62wl1)=k;0MtSZVS(kD+42D2Rl>fd*zbAeHXPbTj%S zeX#N20uB0Jk7pt}j9E!rd-0<>#`g7%Ed53gqmAbP)fIVtzf;RQUcXYJiKmvp*y-76 zxB_J5G_@2-0R#bf;pv@09NB$MN{H{eJJYn>M6{(JTPTyVh{(H6t|j0IQ=oWWg$hiP z$#=N~cha;p!URiHv2aHKEPW&82VZ2kvr;X1ZgNz83J)}sXk?lu_}kFxV5}=D{JsPn zgyie6-I;#dmW7D7GE7uN7=Jpd5Y%Tj;`F-uG^)|mls|Zn5xfLx*xqIk%jerxIrKrn z!u=)@QBI7XLQDihi{;FDfJ?;WNuc|NNvBnE43+)Ff6HEVA*y0AJ$|ak7}_1 zNkF#0bkZM+#MDE`q%Vi0;voFz)`yEaehQOo(0mV}LoSM&gDEoL;v7<^m){hXaAjKZ$DF!)ZW(jvvg(}LM1f1ZU8f0Wo@qNw2#^;^G5!XYJ`n`AAXR;56(H&Cg#G%Xu`r*;J>VI;zw_}V0 z9exSQWRRWv+|3=%FMITtV`qDBvlFgJ(rmTO`neYt1mzMx0jmf#mBJ?0Tv4yLt~Zy5 zsfS?~$!2a?xFqC{%X~uolE7HVh5#ExclPQ02oLcvl`jhR@rB!-&`V!LV#snkyBbo& zEL{hpEF&WzfT=dl|AfD8(F}wUWw89JU$a6DcV-ELWn9f4BC~aXgQ|tK^QrKb?E)cc zBRz$J)7zCj(-pEm#j#Jv?Mb5`fOmZ!z+Z$*5m}hWv-=Z{irR-y!LG4Z(l(hMOX{sM zvzM}FszN0hNKhE_ggyu1N;5Q=#SM_e=}O|jN_asiU~y^D@0;L1S5<;5JjfBJ5)Te0 ztUEZT%x}NQax}ET{8_RI#%gehrRTv-5QXq~jt0#RbM37l`{^!h*L)Y5_>UFPUdY

2@TP33d^1d#3KI@TkyW{|1Nq3W6#tP5KsrFlvm@?5GftI&ntFC?0FoP}vqKX?|um^0h53Bt(45U9Lp=VX8*}4^1Q0vdjpvL0_g)Ft^oK^@YtXF1#0}c^ zMO5{=WPY%li1|Pt{e;69D|RI0K{`QhhTV*T4WZxny7-xC-7e?egoRBjFK$lZ_$?vJ2C@zeP~d;h&UqvR(_vs?2&ZUL?}Za!aK z^8__J1LJt-BDjEG7&M!=74SpzkBf8H-nLEHby>S#&l@}6u4vCg?In)h&msx<2>x9^ zP@gb7vKa(nnq8xtc@UJ^T4VlY*2Q{s|PM@yt&J9shbbEDcDFi*{Q@Y)gucuRb?}_Yd=54 z*A7etL15Hs1U8-lZb=ai@)qgVe1%A9DK(bkS50-lpG}$c6TXt@v8aM9au&uvCLmH} zj7M|QQZcC6?~cD__={zauIn1UHq8&R$tZ7(5GHwcsO>N80}qk3Ecap5;yP}doOB(i z_UdcboSuB%FBTHFHwJ^#)l`$YSEtTs)EXk0bekLbS>OqRK`>)o_B`MnQ79u^4vCZcorvUt$%CC6{C7BZMKwql?BLw|I{^w_) zE>*sONaI5zV{a5HlaXgLcUVyv2utF7+Ls#G9Ryq&e>dh9yv6PnC5>ds)r13R3I6En z?;|TKlB1cm$RN9$`PcoYO&y++ou1WmJwKkwNmIkhO-O*mJ;`lV)C~;0PGJKj2kk+T z4zo*4-EMS?ep3FPAG2qn$b{UsA_;l}n<+_g3l|9INdk<#dY+LyX@GEy8Y93T;l=h4 z(=dd*^29k6J--x&FXk4w`#X2j^8BvINxZ>*PS4+wW0M8H1xnwQ&-Sht>>dA&cfR{U z5W896=1qXMx@k4ZIisDWdyJ4Smh6P{M|ku2yxbTCU60_6pJ)IZNJqv*cZvJfo`st- zq!%tc4Vt5kN~#eiX-v< zwEs7$F&4I}@scexpyd{hS!nlc3%omupP~{FKxVe?(Kfh@9uJ=fgjM7J78L@rQ~p+e zQ(}M6_Ays(*QVY^T<*l9cn+r81wsDj^aid_jkDp-iNsb`Lj%2L`}(=Dn2hLr{v7I$ zqDt({9;)pP4`dl2K920o*_Z^a8>lB_o87Ia$EHRswMuhNhC(1+T(66|IRp>LP!jFk zrDx*f@69UUh%LimEQiMS5b>v|_qcFT+fTd~Af+Fgp1uZDi_g20~tC5WFR z_w`g$CpEu}hoV60iHzC`pVHa+rEy+hpFj9n(|-EW#br43Icv+IUwdD%eVDB%1AQ?& zxvUb3aQ`~9--2G(hAoz}jXKdDHP<9lhTX-4ubTxkE`1(%lO|1t%ZNm!=in+=wm+Dxm4TbRG4+PNdyw`wY$> z_X$qld+shFcv|V~S5@x?9wW%Wz{UW^F&MzcAWr?wMHLrmeRZ>c*55zswYJW0 zkC#x7a(Uh1l9@|WOW~+Hq_x!U@6KDjsp~ab>J@D*9zRHyoyPzOg*XEAB(qMC1V!GI ziA|p1@s2!n`1^~N5{XX@it&`JZ<#$nyk(fSwUkvTKKWoH%0=^uUE8hfAG~x>d^T3* zn7cs)4v0Yl)CSAr>%Nn4OZZ@=zDGa;n|zrgt2mbt2NK%e;_32}FF*jej5TWN&OS)D zr!O6xU8}m;BkVqgx3}OBxqFWQ?XW$$9I>U5S?}*iqZja3y@UJQ6r4=e*2rLs6#N@g z`@5LB*Zsp!FX!FZ-2*Oj8U!8j65fjH2eoWYhk% zZi7hboWbRuxSdGT`8%jZ+beReSmJTdhx)yl*J!})sS|+SHu!b>-oYj>9b~~_&+t6D zc4Blttc6CS2iY~PANI71`&T+rt)9?+t{!)D@-T*j0abn4G_r+omaX$7Y@g`wsC`Lu z$>Ep+2+$3EUiSDrguUZ?8?cDN!W@LgV-nSBM0M<+hC>#}~{Oa#bmwGC1-3VgAM{8p>}gvr8HwnmCK!v5+R9s#fOc^peLLjj*i# zI6uwWiwv&8``C_nde%ZkKzvu~4bFeXulhdgEhlg@$&LdUiyIZ(&W>|ToF?Dr=+1cK zZ@1-6aQP0qgqc({`Ozx-{#*OQxlsOgl;mbYa`R#pQ$#U`Y3SOUhP8-#9GoVrrhy`S zAZ-gQYs#JY@fE`{G<4lEcvSAaCXjt7rj35aO*Gk;_yb#nsD0m$*FeB^!@TI1o2~Sn zk<4WOB6x8`8w2W_!v9-HjM1sa6aC*>{!RgVCbMK~&Q4B$Y^+c6r#dQRc%OSAKaQ^6 zbJZrG=Kfxu^GQT(w#G5ME?u(8}uhIl$PptAI(dMXCdzt%6 zeBca}0RiYDD@@((&!jJ=;iO259QfD=;TSQ~9fM5O0(7JLd}gbLVXi0Q{Ek2iGy!`_ zEink(nDIU6{qQ(ly3T2@zAYE^AB&JVr)*lE#HkRaA`n@v8;!y)%Rc{fMC=cOHr2R-(XOqh8eKfhD2c9>_lJQD!{ z*dTWklbZJBe;vv;44FcVp{k(bp`aT6sB&2dSp#(Upg)-zw!d`pQyg=!HWd>adR}R{ z1T1jh@e`46oad9s!MfXk@Cvfj3x`<0vIU>lus?-GG*h2|QzRMZXLX zJ9q-9ge?|cMOf7~*UXC}DsHBn;m1}$ zy7;@|F)RF44yFfQ19@lkW*!UvX_xr6vgQ8zn4~^s`Wy=EQ(@dcu{ig|^L8bOqXF% z)r>u*K3*6YoOy&!sSeVUTmTps-8#6wYPzwg!lPsa2qbkT9(XqkOPwBe)k?j(FV*z+ zv##9i-3`^tcM_KB{OyWQ0OOzp5HFGJ-)uU2Zf9^}K84q;>!qm`bbqrKGjyetP3h5@ z=sT0ed897`=_-hU;f>Gmiq(JzWuiL!!T#v*im{Qwu{3|xXH??dVKE1-K?axW4?jhU za@D|D-|AZyP=yAJTAVCb+XJ*bzY94$X=~JbwkWQr%D-u;+ecaVA$xO1`d78sl4+O1x-*5 zP3p)3bHcZv00aDb5dt-i9X?K=7XP4`5`mpi|@;B3jX3F6I8;4{(QWQmfSg zG&De=%m{%i+#9Ri-{*3ZZ-bBN*u8j2xkhU-Mm^SL4)Zrb!BbPB>ga9c9z%B>0+EeE z`jig{DYP!p$;XqOrarY80kn1$CXz+;vuv#cBKzUQn-%_Msod@y^v$bM(Jqw%`DFkC z2q$XKHyJ)|=D2c8CT|^Uo*h#*YsNx=Ecbq`Cmy{#S>l=ws=#zgd1O?6veo?@e*6k> z1yA~~v3H6hy5e^iv>&f}$BbjupNcvO0;)FOs<%&x_tp<01X;9;G1+A-V_{d{2#ib{ zJHfVKS0)CK?hApsv;L)-06_xZH($kYNxQl=AGKoP^XV^I8zymaEL?Y6j49&U5JUPl z@)N5bO)P4Mh9qjz96sp z5q(W5KBhEzq=%Zs!x;+{fyGlznG>2Xkigc!&#D+dER1Fqnk`W3?zVpiQ?w(`)vm0lxGiyR97xa|b2K&BVEwN8$31$CkAD z2#S$a2nhiK=o!fcXh3M@)8xmoif8-?Sl>qRln8iV#X~(A#-_NaTCM#9ymN7ig}=WF zGF@2U=v7O#(oW~C=H10YNwssL-~d4M{CFq+!x`Fu^lyz0mbul)x&M1+i=TSVVmUJY z2EJNG>2I~KD;;Hm!OZG_(P+)P*txQYX-p%5ih?@)l5lf{Rg{`NO&Hr>)htg@LV*1? z=a*Ir4H$R@6Qgw=RCzi_9SrHxa!yyHnDT=L2g02+bvN1bCduv>LiAx9mjh~eO>)nF zX!+#WQ@GVbbPpE4(rnXz=MfqYhG!*Kys?h^8FK4@0|o)zHo?Jrg~6Avcb1>h0sH1Z zl??^eC(_GTY~JMb&~nH{7=cz0kyJiQ_MX6ihl!nA2rlrCw(o}^hjAqRjCa5EFo4zp zv%6l8OHmedeX?5uMNT(UPU&HGM}hPb5JV+55HjXd!FtlJI<&UeJGK5*8sEL`Nx^sQ zH$&ya9!nJ=_3I;n%wto_LGh%aHo*C zK;%t%C;(=0{zOw@O!EvZ3>X0fny83^BH4ySY311cWHY|bFx4%-)~W5(Z(_x{@1|8X zj645&`bOyDOxNEh93=UnB7jnQu0L!60}Fd-)r*(_1fd&Zc{4LTv_eGesgSIvOPFt~ zf-uuytIam>fxvR$XF1p1>hn7LP>(BnGc8Oy^vR!FQ+4ox%iGX!TDR#dWsE`7_`6q5 zv;l@&0wc6S-Qhd-uPWH9rgQWx$X#=K)!j2nL}Td^M+?94cM)DMZAHAfVS186Z1~KGO~m?#4&Wygw6N8A!Rs*q z18^-~N}|0UR=j!V2%i(SxcJ{_J1V9QmdaJ>0uD(LMgj(ltSI14J zF08F)uQTBu-v;qbpf;z|SVHpwC*?&7Xhs` zO(Xf#6x>129k`ZCJcO$caTi6R0wR&T z@>jxxW|-}0??4qW1j07R?Yu>Iy>;!th);60Dt@e)i%w3mpRvROBBIbUj!x~j`s)HO zq3<*o>%kBtu7WspL`%=!J}F7gB#=Ua+r|f5qvaoQ*}oLZ9>n*ZyNbpK`@FaVZP2a^ z%~7S+baS3gPSIaTpX{&eS+p2m;o28jd2*zG09XwWrJN5X~YYslny{ zTT3#(t;QJ3WNp&w&@*tBuzq2;t>U1wt0K7#v^6iG@MMg02*&j6f+1v!y01EGFy6Y7 z(3j-O<{KNT0_D)+5Lyy@f_#8YPK*dnL@S>wKM%js@?Ehk6~4{3x@=y{?Wmn6^<@`x zw9pQs?}^9|L{SPynVKNysMhiAG8fxr#8Yq2;)(+RQ$Vc0{GP(iZbDl5=p?_Zr&dS= zKK+IA0~T6CoAQH-21u4^9uDR0ix|kF4|K?yS5D%FD|TD%J(@CUEIBAiy)S~Bdq-JnDgi7f8~V%(!wh?}sl5*)zQw#Zo5K8G9qhHDEP; z6t;1n?2;Z_QV}W=VBqw{5$xxOw_h?vRu!-Lima6}>H)e(DW&yOd6{RBe|(Tj&%$%e z@31^~{*ugZj-BReY6ge*!E43P=IDyHXi3NZNU%AgL`Uf|GSlSc{3o|}?gU}jO>OuY zr%gI4D^gxzVtwL9)jS5}%}({h&MW55G;`Z1fF%5)Fgt4-19g=|0x+s7D4ax*j$>{2vBk|Phd;og4=swGXJsFQL;U$e zBhUsn&JPL3J%iYD2~5M&;!nMzR+{wtp#OrhWrjUxVGq}ja1F^4Ge^Sf86}mJik-P z$9@(evvD)a{BOm zIc6xFaOA#9&-fs2h7dg1%P+9H;tbsHpVk3t?sCe-mo-N#GpOqYvR8cjVRO^5wAWRj zdad1O1J{M!x!%hK^FLkPfA(KsJ2F@0xY*`0X?(;khxa(<``4l7R8~FCviqBIpI6w; zy)5b`9B|>w8BP`hL~u4KY50qYs}=X*b8R~k8tlzv;I_)*hT z!oQ%i+P{GLo=iii^lW|^affoGe|X6VnY7S8FSop6pl`I@Nrr1RD}(A6VyN>aMzrR@ zDHTP^{IS8BfL&)dDPmQj`@Wz z*4a!gyPm!`uOTg_Oot>7AkIq|@LyRfoLV3=*YE)66v`k(4PGVRt#`qWOf#InOc6%2 zLg0gy^QT9uc40C9%>KKjGrFHU2S2wldRrvGc*+ddf?sol+$0*~8+BFdh6u;4@foML z|0aU17#ttR9+H~vEEt%5qqjs*f%dz>Dxg99)3eBJ5Pd5OZBh>0%!tBP($N=lMt!C=8seeh9kOG zN}qbS86$f@f#9^aWB>{p%-&i=Sg&}Xzl@5cx7b9z@OZ@m*EIh5?9DAWit5PPM?;XV zT!1_7r$x9M`>S|>>$Drd*IKXYR01OC+u+yf8PQatu$NC-d`>a`*`IgcK=1od&pRwT zLr`%nUs=wYU472(MvpnK1?&e{jGi=o{_k+)EI})RzM`cQ#{}ut67K48h2$^|@e(j9 zmQy&ObDgG+d)UwXxjek1U^AEYnDjmCCl6@0qyl;yVfIjKS`8qzu2G+z_+&~K4rU3-1r!Z2>RSzl*C6?Y)r_O$uL>R^a?yugHa z_56d#L+de3tS~vFH}%JUx{hoSO)^J$fq~j#r8sAadFJ!LDtzlgMh-9fGuinHI85|U zl{q)j=EgaFhC969ULDS(+b6cZsO$A=g-(WhrRVlCvLN7b{`IC z3D*}?UAmnefycf6FgpmCa!io~SsB!|fxtYVpc)9DZ)lOke06Z4A+$l(ECdiJNTJE~ z^YmVSKr~WOgn=~Yw4AHH3@`!+9&c=!b(0e~wfH$EqWL@e!CDrR#i|b|<-DW8zN6pS zt$Oj99Gv-j$ToEiy#3Y~@{moP!Yeum(ER zqGJ6RQj~1KF#1L+tEC5XY@?V19l=g(c>ecWj;8Y;FcPzxW*utpgIEjJ5MOJ|i>NsO zEkk22t-8$&r39xs>C&(%k$^7b_y0OvBi?>Vejg>|d2SHF83FO&c4gD>E=XyuGz-%M z!zN`G`ERqC#QCGzRjC&cOL}!N)DWqj{EYaI(&I5a;f4uQ%4@CHFr2H1$Mvq1a!nPF zdz}TK)H*vKOv|hIxAIJL(!b8Wg!oVf1iWuS?#I7B8F+K0#_%wspYgyF-99^1y!VLd{>103$TUBSYH*5Y%6*a(=rfsg6`;J#n z^>#LYXw#)Pi_s}+00a9gTnV=pTVbZBbx*AY9=UJp8sN%O7Mw;gP z6x}ArRLnuesjEWL_*tu_s4Oa&-+|oa^W0jqGmgq77rS&SkeU@bL8B?$4M3df@Sj**?VF z#T`{C6#LO115hKc+3tNF?E#aA{cixuT;qo0P!$D+lw;Ngq~wjncQUAzdnjxoOXoz;ZvToHm2iAo{oQB;$Olf$l~v{RO#BwLNm(zp@0VF4qCY3(LG~%DK%z(JRNX zZ}{5K3v*-J{tet(T*SJuIgG4{%x6k&A`~SX_S_}DyomlHh49{EHZ+q=( ziONAS0Ui01gn<}6Mj@Ljg4r}g1|N)Ey2Q1b?3Bay07e%{bIC(oZVpz7dZuL zw7eK#Q548P>F$ZJSKR=HasS`)DDg!a$0)~XIq;L>F|qJx?`lv3(yw_4b`n-*Cs}?JyFwoM=?u0!lqwhS{0`#zJ)F zP4h8~oP#A^+gguHXNk%)4RpNip|5w|%9T=|Fp0pn>Theso2%y+(!;LXv$#6n-9S1m zS^#YvMM)f`Zj(>_QP5ewZ_7O^oBG;JJol^uBAc}9-tM2oZnuUlv{jG@1>k`MfFdO- zeT6&BC?6NV4`H+lqGkXQ7Riac3z?BKRvSe!g60e=^8X$#-~bzuV$RHlp6%7BedAUy zTG6ofnUN08g+=OpG8De5M|=JrI^JuM$7AhHRzjA$`m($@=N*;B8%4TuLdyG>?0f1@ zmaj)%ed{aI_h6{=RpKC5un36601@C36UZV3Y1uf8U8%QezxJnSw^Lg9GK@OYpon~y zw3LU^Ry0#TCX_N8A49{(*S78q_I79fTA7vR$FU&+DCD@&&M_%m{pckidn17{8#qlF zA0K8KvOZvMMZa35Wo?u0=<)!*;@|7;f97JG$F8Df{i1L@y8$H|N*_oF zM+=Wgoy3|xCVr0L`?EvJry37g!x;1o=0Dl`ozE%SPjSG+lS_tqFi{1qz}Y^i1I=-r zhp$jL;W3#Gf$H5e5U10T_#vwnfJ5dG?1RYus|{=f*3*^faYW3)(3A0o;nx~G6CxeW0s&^AcKrw6 zkJ+X_a_UZZp!VxMSbCg>psGE)-nhZcKOqhzzU0)oxIC%aneY@bY@{*fd1wJk9fdRo&M7{)P(#sJ0y0fB%pF^ppv zi~k)C?3ZFlghes)eG z8Q{A-mI$3LW&)2Iw&@U**rOp;qyPYq^eytUYS8nPdSuCgr#|1?w4ZgXJr?;Gh`??*@q+F9_soIq%!!X<{Jvo)&D24Qo$*HYjd&7hWqZakwntZJU(b7h zg2q;0LF^l-mnQ|2f*ctQR(j1q{3whnwD=rBcj6+9`IW%l7g>*gvF2DD6H&H91_Nkdz@~|R2it9e1wS*`RdU%=5eNZC8nW0dQ%0k?j4Z!^ z=VT)qvkvlYvKrtms;kYBmEPH_F{^!(sOWSYZpMSspq8NF@m8llq%!8&Qd?=LfZ~xb zy~=wQ-8+o19FF@EBpk(qxDpmUrM$?cN}d55_ehLot3u9z8SnwH1W402{`78z-yJM% z5�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�m2NAc4maG(DU6?|(mh;a-UgCVru-cm!DX*^b9Y4PO#QO9XQ?TQiP|Uxnlp zmG{vwvphRpJYBb>xBKDB^stH=_RzTj$65GNP+a&Amm*ET&(}w|@$ZsYbmm=_716nz%7-oC zH(&fR76G{7luwi@@i52g*n8$!Dmvb~?o=?v%pY{fj#-dG-o}JiY#sWZ(u{!*M2I{f z=G|*I%7`lCq13aIdY^^8h4>IS+hM?sRBk$U?QA>|2c!n%V8tYOJ4BmJ(NaK0zhqcq zMv!43ARD|wzBI%*pn*iQGd83R^6? z&u>bI!jFh^F?Af;x;!#)$RnXEw|)_}Z)28zgCR`kp~s?NgPhG;zYI}HGmAh6L6PlD7)b+ zlyNEl+&>j8)vXd2 zC~@R=RO(K^erK`os7!zd0Jb2Sn`$F}jD z5KkN~e<1hswS0nv&*-R-|K4A`tpYjRBekvv7`*RXq4}3}esZNm|+qYxT1T(o@SMb zFlIreIVm{e>y;rQu-5a+Lkzu9#hLh6AQ|x@!mAub6Zn)lAQ00y?Yd~WP?SQfc~B8i zDFe!9`keY0^ z2mlux-lS-k|2>nhCDxuGAb_8Xr#(RWqI)7{Xx6@F<(WD$-8ZH@Z!0`ux1R_3Et&?X z!LCYaVjGQMk3VX|rTECA(UG@56=kIB*G2^i=qqEhmybWjA`jL>kqTZTqYusH!UYj= zq&_kZrR9K0X59~eN2{lR;C^ki1l3)zyY3Jy*z@+Yu9lOFhPPp4K14gu3VK{-g#yAflV zNtFhMjv0VM-)~R%)JRyS7zB4&tZUI+N99>DWd{WaKhi=>g!=^0o zUiNBQE|%Spow2?-_WpqhMUla5kBefrVxe z|F(^F%T*ahp{2KmABFjW`VoIc6^Ec&%+?~h@gdj|_xCvIf;MGS51C1$nTiAh)MjBw z1@MipVc#>G0K)=V>p1|!0aCtz*%1qaNYDQqoZ+F4|Ej|lC4UMWN=O>hw3o0GhL*?9 zWU+43QJ8ks&-GCtG!1Uf86W=t%+XCov4DZoQe&2*5%#-45oi4;wNT`>Fp!Q1$}`JT z6d6Z!7IApa}eVvMunyk#6m1^@8;xcZ%+Lap&i>}o3QGn4g4+POGXe|b~J z5gnd|=50#pr~n{=n$3+UI!OZ9J%5Tq#kIL4D!1sFIlvSDSY2Jrb*Kc2CF2h(ieoz$ zGw4cx8x&!qA)&PzRHQgI0d6|;Ev|GxBy^fS0(%rDW%9z0tJPeJBjc6nO3M3xn zCHj`slT1+kvOq8fxADS0eLMx_E*5r35rJb>ASn<{bQG)lpeOzFF$6TeAJGMSS?OI@ zL1`-;xPj|w{el=C=!N8|l=1Yt(y6`qxie%Om$w!$IaVcBh}_nkR{<`-({lecYaY&r zJjddAmLqeGQvWNAOX1Sn^30QVxjrAk9n&33X-_8GS@2lyo`o|18a{^u^d5HSZCQL!3d^7r)YsZHiG~HtXKKghOin5nnnj6Nj)T&qU=Zr( z_6;ppV^?AR?b$?h_^(w|=j!X}Q?h|*>;~(1Z>uCT6k%xn*IkWYtoWI2GYkdK$G^g( z7Y^d!=I5+>leC+nX!`dX13fWO?MTY@bKTg4Zrq8Wm@CjEy1dMHhQ~B~nw)XIhti{9 z+IK0Qm&{e_%{=y{16tOd4;5~YK-avU9$Cf3GbHgyOI*KKyl8>ERSwo+m=_n#%a5P% zdvsa&{g-*c&liI?_1wLGuKq5AHT`BC>JDGzAV;~F5)cD?kHkQ&3};+`Hj?eU@NmwF zGMtXML|1+ZOwg zepv|qk`2aX^sQ;jt*e|!nbF7mDE_lV3*I)meM~YG5k>q2N$$>hd70ZdjrmBwAeE3m zp6&YMIUpJ|he-r)>m(xYO+(9QiO?JS3Hzin@xoYOD?>LSKD`UmdBjD$YsbZ6u*fam zqv<{unzBO&eP|PI2Ot+E&TbP_>Wg@gxYbRVnzBFwm9+}k?~7rONo{84$r4uL*7Bmt z+y}=B-VyCf{sYF6>-J!_h)mM`}v>od387kmMaHTO__4@@lR^=@r9siuKgA! z8f?sfa#iG3X^jz_)CNe!v3X#TU}Q>8Lg1Tr?)m&FMizr`>3yAn=mYekdHGYV7s&zR z1#Ptm!6qCP$$Ac?4SymGzD*Xwro_WgsSxp4*fD>^cvb}2HXvgvw!Y7>;NQA!bVqbw zsb)AyHj*QhJx`{Qp11dX7{J4N*ztJdUG|Khb0Q)hSCcu*<3|lt#y?i#HB;|tc!aPg zvZ7EAGfGm?z_^PgGTK5W)F;3GutME50B~66_#1r@sR-Y%KLni75Q3qX=Z`zUN7=qt5Hxc7kH8A zt{NvMfHG}j(c@n=Qd-1bxbXLDz}M{(Cf`2u&Ty>)?@NT_TMl(AhW5RfQs|C~+YK zR0@`927F-+Azw@>8Ij_SQ}d(?KBye|BSQ=a4Qu<(A#Mhj5P}rX5}mi4Y3J&*MPQ|{ z&+bxk%x$Ucry8ZcuV1IUBurBgvX@}nmE1V|=GQE*6t2K1>l_aJ2aH{9gsx6l(chqf zl;C)5dHEO+BrMOYY7$}&oX^~F!SxqSiYxo1uPQfHhtPWe+~7?*7=2zFSY_EV&gPkqlJ)|nLf!hKR-?=PTJvi|qJ;u3v5!+YS$ht_HppS90CXO@Zt` zSG|^gD6!SOhjUl7ZK&@iJGkQpvclEWIm%6CkxN|?3^VMZRGuTaAwA%M$O;%!ku)^e z!0-x?SAOV&!rwMm%yD)3_|?zX45TWBv3Kw2&R<4+f4dv=MQ_W)x;RazSY=#IVB^Sy zB^xH6f9_|z5{O=Ho`oM~C&fMJ@k>S3ww?}Os@J=*V34`O`_9)4h*GEELz0TCt>*`~ zrCaKvX|!-5cZryz!@1Z#OFT8#1=5;EE-4_`;DtNhs`_eG5a30E&B4EgA>S!o|A@1} zljw~frt|;hRMjJAwdjd1od|03Ob`sCt7#@ft`dRLNs2D+$G-CTvSq}HETTFmBY zw1vf{cMw&lB{m;{|1#)U9t$SN>ttK0R(L-~Mf=c2d8dhMLlE3)uIQhBBsPgS6g~XBh`2_C_#=<~OfVp1SzVp=)cTNDE;{k+*5zzFZ082tI5GeyAD;Alm7Xv3R;4#ey%>S zwDjXdkY`NBI6x^lHZyZgo`}qfF`7JlpQ%xrd?8fT&s9g6LOtGp0;+a+`HVq|)xB1a zDh6JXTCc@|jPjc@nVLlH;oTSpf?vCVk0!HVdtcsRG#K=(vg5&nO`7{db)~h!-brW* z{;hkNbZV~B`pKtQvITh+tk9oae~>AL%7%P(G)PeGv=-vYI*nGAsB})C26Db-()2P? ze88B`L~HwN9VI=!OB~AsR_bXUj7RiR+>MeN;)zYYnmV}a(V^?QGKOdR9^v)YNeF+d zM|WzK0yIFLTG^C{@zD>3nVyr85h|`iH))jGG?%sbREzwZPfnc8eakMP{okZRLtM7h zv7XeETTPx!si12m+rT=n;n^!%2|RlijW%qZ$5tExP-9MK_@Z-b#0a#zTWJKyY0yX`3f zDv-^GoSnMpQ5L1U8rTM(v~_)IBrK?mV{i5Z5~4sc-k*bB8OwZ;rk4oFJHf|>!4CTzl@LauS@wuQ(@`XzK*C*L239Gwp_~;K76f!d$fAjO zxCG45O*pqy6vc&PygH;YB%6Gd(bFAw6=S$=BFaF0Tv%U84CJH%(Svr?RZf zuY*w>lwjl3orw_n76~Ht-0|zgS+C#iOH|fMoiv!NwW@@kYPN<W9rz z`mo8#oI@N%8!hYe!Tn}k2)D8JC^MtQBO(}xDt>qtw6QR?rI z=jl{Nq)jDpZ(}}{MOIvgv2h=&@hL?n&MoH8RKCdy3c9rcN36(`_8R@-vaAOu$C9mD zV^N7(`1w%Sw*I?nWl)5xXzA!nQN6R9eA#Hp(LekbquKnPYP>^-i_-Qlc%NNN;4r|A z-p{EU3@Nrh(mWutUDtZEu43j)Z3k@q51c_pIR;h4_q+R_8QcVxsVlnKE)6zct=&zn zk&f!_aY!~jeyj{NaZhp?nvy=686@it9luZgtxiAmamdqe;XG|K%0QqZRs5(S){V0b zhvGlCuS3*}C_DPZ8T?zE>HUY zL6d!6W_d`3YWPMh;5a{dz;%mf-0rU%j`*|OtAM==+a9j60D=d!7F_mxD;-C6u0_+$ ztE~E~XfC<{Ja-RF=?5w?uv20H|1w1$BEYlc!#ljW; z6afJ-_p<33Zw1;S|K=GJn2@z>euW1Fx7V$11ZOyMmfp zK}cfWlet49wmATTY)3{l8M2yiBP{mQIVjGcYsGZrj&50Bl>#86nVlmNnPzZEonv!k zc9!{H(Z@OTQJ1=A`}(OK=BFKw_)725ZEt_*M#Je}Z2Lj%KJgQ~!T^e29`_Yi)CfR8 z^PVZ(S&Wv2JS##3J0l(QK$_N0ejA!nXp#f=zE%R#669rC@E7j2Kmd|>n}cOyYduD^ z1kmg0qSyJ_*OokneJcKxly~+^s^$7`75<#L_e4)rOKaM-%)kN&8>Y-T)rkhu?s)rw z0=a_FNI=CUyKPbP^R8q>P+fjKc8v*`_g^$MB}|TV8Oo(=NGI(n3Tq(Hr}uZw8XvFN z+=~9{I9Ax!CjZVvR%5T6@F*zbe488dR3zt7=qSL-gi|??NHIv{s}r3=rgNmRBc!SZV!;&< zGAJZwCJ3Ui!9>al6%i4V0sw(VKoJNBtTov@_5^B3E;Ef92?Gcug9R&Tj1v-RgGUUE zo_R`QLn%-g3}%Q1$)JNv0>uM?loAKSH8ZM_(J~ryAd!(d%&}tyPKrt*b;^VkMKoEU zs!Nkz$zp08EHY&&Kw?~ttTYffV*qUwOgQtvsj_Nlps3hIVxC3_aRB2+M9hhiQ6fQs z$RLvQoh7Lp%vPj}f%#9Hq=*ZDX03jxuER}Q}Ow~Z} zJVzcvkrEW3QY>16K*vQS)G?Js1dN&}gwi@HoWV3gC>S>;f@fS{fJp6zjH5hCqM4?e zsv~6(A^=m50)Yg9%M(7M2b3I1ArW&_5GIO+p&)W0B0%9{N}`#NK*w03Arwr!8B`K7W-?(^ z6Ef78uW|_y(;*T;l#C$AnE=zwI6_DYYNwFb%A#;CCEGm}4Y!r9K_JdAY_cHCP3&J1Q9?W znkcd`NfQ}*VWNnnn?w>oBFMpLGKnUt#MMzn=VGbR3Y1MI$si#1l}+qS|w`L?p2z83m}SqASdT z)J~F(#v}odOdQ5RBLf)5ZBcqb6x47kNu!K_dgCV5B#r<>AiHU=y}X!K^d26;BGRYy9=o zKe`r*|95*!JIIo45S{*Lg=!}XVy+M!vn`vlkfa7@8*6_g1qKBT_gf#H1=Ei|(n6Zl zR;ZL6GArq4O}lwJjA*OBP?YV;ipcnC9ZCv+*ZfVz8$;)OL7gMM#<<#GR2)k-AbPvU zLn`CBzAoLWe4CC?ZEy)8{5W0v{UAD@E5>mV&zieS>Amw5%8wJK0$*5@Y@&U?3^jE` zywm=aNAy!l<#~TS&nRS8O6+zG_ZVZo+Bp%9deFYM+H_65*v(eP!y@gLZ02oq6))lkfAEcn_FRDU}V6&fPs?y6frq_Ezu8IG^smzlTbg z-^spQ7;eY0nfPk^-&CX6Exc#(XkkNkfq7X(Gqv#XH!L9#QSI%d{ z67&x;n1=iIv2mjgqZdi^64-CMYV>0$(MJQLQP>7nuXd2J+VnO)^$O(@mR$Ag9LBZ0c&BU-;7)WVlP^>WQh*-tQ=k3pDp zVlX-CC@%_J@AT!dsDH=GBi-z~oSB763~C3s!b7A9C342&1|9zGe0M z6@pg4(-P-w)iK3X#qPs;HNjxSM<^c2bcD}wu)`4522dRmf($7oIPypumoYn zT6Io~p8VX41`PxU;v5aA<@$Yo-xQqmHoP;*w}Cx3yGX!Z#9)MGieBWG={?wUav>S* z(*pqN8T?L&2Vt&$&x2e#ou40~*h^reQDCYIjVPQitrc6t-kRDxBxcF)5~?5gkAt?) z2~Bp&btXBm**`-fA?i1C*v8M8v*r;AL}R*RQw2Dta?Hx(rt>G?!AGcyIJXb_Ss=^s zw|$48T6xvE(g7Dl%dB>`o%5hHhjf{n@)|+0w^Aj6Q)B8Ghaa|W|IRXk>=>X3 zAP`qE_3^dlupq3BzJtO9(+x3!*om`nDLFoFsV5{dpP?d!26?JwJFtJZEF;|CNu4U) zc|QGUAsP*Z0^E>)FPF9txXNV7+*@@;v+ets3eRo|bCiGQP|cvhR&nn@0?={ii7Q7O z=G6Dn>pc7*fzU9K*=NKB$fe^iM|M9ka!TOQvSh_?Py9U#g(x%ZVO;Ziub8A-8IDeR=7asL~1dyzhejoDr9%P<`!Ln#Rsx;heda zLg+o@n{n`D2xB`@2ryktemu4HW&KmTSyG<=qolP-hsYZ~=hSoZnjI~?kUIXT&M*rj z_JkgR8_-#JTZC0Wl{!|@4U%p-9OOISD}Q*I9oh@%00ja7l0F8<+3jhvNOTVzJZKY` z>i@|GdLg|CZXR)OzJcc1vAF%9f&kOe%wCidH~K)yT!CD@hma@Wr0OOqXr*+^&qeSM zYbqr=#Yg&jHjg2`siT+W0APS<|FLL9yd#gv`>`B0a0 zyu{LJ$V{C**uU<$;(bwP5wMtDW7ADSBVARojP`~r?^<07`#@ejd0$3*13?o?a+691 z1sS(cNt1}1>;Bi{zSovqk0hV9!%+i?>W82UvcVXt5JL8c$`gI&)<@R%x#2(Itn#x9 z$K^5$I@i?bc!qji$a|z=KhRtf0{|WWd{aBF?EoK$d(Z*S>N>CZ`y2gcFz@{C9E}Bs z0w|*Ke9B;bM6o0_%<>L_8In$4mCKrB7@)Tr=LzKjXY_B|MkE5D#8gKNRDS07j-jL0 z1Ym$5FeAWF9qrEa@!uWRN{){iJop) ztAD4Wuw}omykMm!4dPldV)_}n7+{AWWz@~Wr|Kvslws?g59Lxw`vINQke$AmhqMEgH#J|u=$wBUs$@Zt5V7uJBrZR;x2iVD z-ZL&VPIb43>!x?R*xxrbK2Af1&h{DIMlJS_^m6WSk2I>NwLc#`nSfIE+V91;cVuIS zc)KD0k5xO_gN5a!ImK;dY0ug)L@F8>8qJ2Pc|~|hwrm7fMI>l9&GNtOHQm!i%?{Md z@l_8*{{J?b?g(@6FkyLw=xS^TfWh)F_CHD`fGQyhUZx=Ivh&?gu<1l8#fj-|3ZKqk z2|Jk@ya)F4`$&ejOcs!&i_sh$o{V_ZAdc`;PxvvQ_$;mXu%IU7&6c$4V;-}{)# zdLK78_6=)&+lnKLYq`0E%zb7avy!hdcNcT|cq&UP zxxXF4gpO#63#fJ)&&rW#!Pgh*GQ_3#!t9lfRw7R?einxBo-xxu-rjH3i3~BQnMT{r zyCW(T&t~Zt+8hA(=|@C?_aHKLj?XnU1kLYWc91erkZ_-Q1P0z8RlWvOLpz_4M^Bq~ z;t+6Unj^9?d5Fc}%|OBk2if^BOoZvz$9BcOpR(?%&YDh{)SU9reGT5*gO8lW3KeA5$Nm$TAhNixo#Bn5RC$l?06IeJt2N7~abJ$NJat6Ru^_(kj&$_b~ zq^GRzA)RabG_Hx&1g6dRD3-pbK7jo{O;u57FXulI_b1%ATw@RON~&_rkv2XPS)tI} z+_AvR%=IvKbFB!6n$ zJBlKmd>SLfkH6NLMdkWk3=(&26gB~BFPpELje2uDdgCSAtTiIo_^rCaVN}fsn!%HN z?9K67q0d5zyytUe1jgs}NM44Q-g0vF3T93Q1=ByyR{q?|AC3w4>(i9Re=es9mQ7w_ z1?lVYLqq_{!9+BZVM?ROksmi!BGTaXL)#tSBNM>OL`O%W znx`w{N9<4NW5}ZaBp3Ykas1MAbr^>bEX|_d8!}iPcQQ z>(rcM#%fI#Dn8(0C3LryFK9i#0QTF_Qp^9Mn3w~{+?(81^FQl90f%4yi(5^pzCOJ; zg0FxT@~g@cA20M(8a0os_#BD;z^6pdN+P6OOyDR;!CwzItOGqyvbb^sk&*F+KkKIE z5X!Ohm8$6D7QAXs-|2z~1^bYD#xTuo-P*J*1v!-iOnUsToY=n;QVe%E$&y6R1F82g!xurahL3ql)Bxy>3ww3+65mF*0#P3I8!vCbf8S(Q0q2D(qp{BD>CX9K|5fXt;Kk0;13DV4 zt~W9Ot*lqctavM4w_HrIIq`gsoy*HYTR!KdRp77H24B;N`9$3d8c)m;>Ru4fard;Eu)CdiQ6eOrUVwfwV{dJWdk& z#)uDf8I%Lsz0LU$NL;!1^#EsYt>|d3s9LM^X{Od9Ut9egX1s-%%7OMnuZ>%K`)_xPsO&`pp3=@M=K;NUtB7Vw|QjCyEg^8 zQyW4a3z|T$7sbPJy@SV6>;w=#hS98jWZB@MEe7|@Jh7ziLBP0!u;#9u9*&iYM) z2nxcy2n~Djl$$?K8fTNA_DjdN=hfI+bg4QxF`}f|P2zmEn!?T_MA_H+4LvGr#noC- z!Nk&ROT8#$k~VQ?%+`Tij)Fu<4l3#Z}M$hI_S(39PgZ1UZ2-BW3xVUei=l==9(&?$T87IKHicU)QKbNny9 zHrIbC1Rj+EQ=v&TZXJpRmt-`km!_5-Pnr`lU3b7o{IcEElj!EW^*&*Q1qr|MB6C@D|(H zM_pD$X4enNNq0A|K-&7>u7?&xv4n3LKeOBg)J6_l^XFr9<|k;KdV)I^q$t3G2f#3Z zeC_c0)sWSWx&NlC&8{?RivXq>&igEY#-($e|5*KB=CGEi8+(i#E^G8$HvteVVg52O z8I+Erg(;y>i(!TamIbW*z}svD zpOPz-yntz_ojO=>d+$YVHCC5w*aGp0pqoOVo4Vvty(rLLI4<~=8f(@Tv7dk=qBMfN z9t*=lKYHZ9q*j~0h?8K+o15Px8jaS99uLJRfCWx77*_*>)^YD`_^J8-gs5t)nYLfx zAiL(b?_}&toVKwU#ccMC63{!ND1=|KnT#NitTSf}nEL$esKyiPX&C9FLvL%EXEIy7 zij-5`j{SCv;{zey8oxr5?{~41N%TE6`%64lSiAQu=q*;ocvVEc#v0x|L#1R05Ac)@ z?xF=3_%I;Lj3{i2K2W42UrOJ-lq#2F*4a5$rnEq(FI&(-YNBLlwq6{90FFg`EhF9j z#~Fk)q}tt8x_M9$QC}HC%i3HqGuCy`ZTFu^pIq;@51LyPdir6Qe{yQ5j@@F3YGzP208)Uwun*L>>355vCR&kpNt)U>G2jEN9;d@ZTJ* z4Qc(*PM8gx+VGRnQT@$G=9;hX0Z#M}DHp!ouPmi&?2--&_vL-+iQ$l{Hz*56+HG&= zvRzrfF~<$gBtGR+WcNHMio5?ykt1fTpniencQ~70^}`aqpP%+7yCE8)^61@c7{A`-(4>GpS4UQ@VtfzGIr)p>pwRe|B`k zwG#vZ&v22lg9QiVPM7B+#+||XF~L&|yNLJr^1lAAp)_YHI7ZC7wmz0x0er9sw4Y;b z{XZ*tU3*hWo|M8%H8?#<_Y~$7i0rr4*tXWiSR@&aH$=aH2x2n;eXtGC$65*o=_JAf zMRq&q!;TJFhTP~S`}6~fB)l_^F`P1mND=b8x>UsaG5hd*;(I#0PZmf8&;1}h=*~1z znlV?$He=h?>VZ#r%>lXUO4FhB&47xk?r+;B4_xH&6^Z2q1pBvY2gG zXue?fJW7be8!(GrPOpFGJ|3)8OjXycABV&!a1}{$ph#u5J-EAE*LN_fvi_LM@|r5R ztBa?$lg#PBf2S80ek(wy=Y9_xYeH#Q⁡)?!VA%M`ZE4rYkaUbEQU}+lOVSQ!{NY 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 diff --git a/python/tests/reference/Result/read_7.pbz2 b/python/tests/reference/Result/read_7.pbz2 deleted file mode 100644 index ef25acbf96aa769bee6cff443e5ed594eb421e7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7734 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 w(gks^_W$84g~u8r32}.vtr' + last = '' + for i in range(10): + if os.path.isfile(tmp_path/fname): + with open(fname) as f: + cur = hashlib.md5(f.read().encode()).hexdigest() + if cur == last: + break + else: + last = cur + time.sleep(.5) + if update: + with open((ref_path/'save_VTK'/request.node.name).with_suffix('.md5'),'w') as f: + f.write(cur) + with open((ref_path/'save_VTK'/request.node.name).with_suffix('.md5')) as f: + assert cur == f.read() @pytest.mark.parametrize('mode',['point','cell']) def test_vtk_mode(self,tmp_path,single_phase,mode): @@ -416,13 +438,13 @@ class TestResult: for key,value in view.items(): result.view(key,value) - N = request.node.name[8:].split('[')[1].split(']')[0] + fname = request.node.name cur = result.read(output,compress,strip) if update: - with bz2.BZ2File(ref_path/f'read_{N}.pbz2','w') as f: + with bz2.BZ2File((ref_path/'read'/fname).with_suffix('.pbz2'),'w') as f: pickle.dump(cur,f) - with bz2.BZ2File(ref_path/f'read_{N}.pbz2') as f: + with bz2.BZ2File((ref_path/'read'/fname).with_suffix('.pbz2')) as f: assert dict_equal(cur,pickle.load(f)) @@ -441,11 +463,11 @@ class TestResult: for key,value in view.items(): result.view(key,value) - N = request.node.name[8:].split('[')[1].split(']')[0] + fname = request.node.name cur = result.place(output,compress,strip,constituents) if update: - with bz2.BZ2File(ref_path/f'place_{N}.pbz2','w') as f: + with bz2.BZ2File((ref_path/'place'/fname).with_suffix('.pbz2'),'w') as f: pickle.dump(cur,f) - with bz2.BZ2File(ref_path/f'place_{N}.pbz2') as f: + with bz2.BZ2File((ref_path/'place'/fname).with_suffix('.pbz2')) as f: assert dict_equal(cur,pickle.load(f)) From 39c0bc9de64dca7224a0800c9d7713508c0f7c6a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 3 Apr 2021 08:08:48 +0200 Subject: [PATCH 097/219] polishing --- python/damask/_configmaterial.py | 12 +++++------- python/damask/_grid.py | 12 ++++++------ python/damask/_result.py | 11 ++++------- python/damask/util.py | 6 +++--- 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index e2762be4d..2a1c4da83 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -1,5 +1,3 @@ -import os.path - import numpy as np import h5py @@ -159,18 +157,18 @@ class ConfigMaterial(Config): f = h5py.File(fname,'r') if grain_data is None: - phase = f[os.path.join(b,c,phases)][()].flatten() - O = Rotation.from_Euler_angles(f[os.path.join(b,c,Euler_angles)]).as_quaternion().reshape(-1,4) # noqa + phase = f['/'.join((b,c,phases))][()].flatten() + O = Rotation.from_Euler_angles(f['/'.join((b,c,Euler_angles))]).as_quaternion().reshape(-1,4) # noqa _,idx = np.unique(np.hstack([O,phase.reshape(-1,1)]),return_index=True,axis=0) idx = np.sort(idx) else: - phase = f[os.path.join(b,grain_data,phases)][()] - O = Rotation.from_Euler_angles(f[os.path.join(b,grain_data,Euler_angles)]).as_quaternion() # noqa + phase = f['/'.join((b,grain_data,phases))][()] + O = Rotation.from_Euler_angles(f['/'.join((b,grain_data,Euler_angles))]).as_quaternion() # noqa idx = np.arange(phase.size) if cell_ensemble_data is not None and phase_names is not None: try: - names = np.array([s.decode() for s in f[os.path.join(b,cell_ensemble_data,phase_names)]]) + names = np.array([s.decode() for s in f['/'.join((b,cell_ensemble_data,phase_names))]]) phase = names[phase] except KeyError: pass diff --git a/python/damask/_grid.py b/python/damask/_grid.py index ed44989d7..cd1306ba9 100644 --- a/python/damask/_grid.py +++ b/python/damask/_grid.py @@ -305,18 +305,18 @@ class Grid: c = util.DREAM3D_cell_data_group(fname) if cell_data is None else cell_data f = h5py.File(fname, 'r') - cells = f[os.path.join(b,'_SIMPL_GEOMETRY','DIMENSIONS')][()] - size = f[os.path.join(b,'_SIMPL_GEOMETRY','SPACING')] * cells - origin = f[os.path.join(b,'_SIMPL_GEOMETRY','ORIGIN')][()] + cells = f['/'.join((b,'_SIMPL_GEOMETRY','DIMENSIONS'))][()] + size = f['/'.join((b,'_SIMPL_GEOMETRY','SPACING'))] * cells + origin = f['/'.join((b,'_SIMPL_GEOMETRY','ORIGIN'))][()] if feature_IDs is None: - phase = f[os.path.join(b,c,phases)][()].reshape(-1,1) - O = Rotation.from_Euler_angles(f[os.path.join(b,c,Euler_angles)]).as_quaternion().reshape(-1,4) # noqa + phase = f['/'.join((b,c,phases))][()].reshape(-1,1) + O = Rotation.from_Euler_angles(f['/'.join((b,c,Euler_angles))]).as_quaternion().reshape(-1,4) # noqa unique,unique_inverse = np.unique(np.hstack([O,phase]),return_inverse=True,axis=0) ma = np.arange(cells.prod()) if len(unique) == cells.prod() else \ np.arange(unique.size)[np.argsort(pd.unique(unique_inverse))][unique_inverse] else: - ma = f[os.path.join(b,c,feature_IDs)][()].flatten() + ma = f['/'.join((b,c,feature_IDs))][()].flatten() return Grid(ma.reshape(cells,order='F'),size,origin,util.execution_stamp('Grid','load_DREAM3D')) diff --git a/python/damask/_result.py b/python/damask/_result.py index 78f30bc3b..b3e803972 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -420,11 +420,8 @@ class Result: for d in f[group].keys(): try: dataset = f['/'.join([group,d])] - if un in dataset.attrs: - unit = f" / {dataset.attrs[un]}" if h5py3 else \ - f" / {dataset.attrs[un].decode()}" - else: - unit = '' + unit = f" / {dataset.attrs[un]}" if h5py3 else \ + f" / {dataset.attrs[un].decode()}" description = dataset.attrs[de] if h5py3 else \ dataset.attrs[de].decode() message += f' {d}{unit}: {description}\n' @@ -1127,8 +1124,8 @@ class Result: dataset.attrs[l.lower()]=v if h5py3 else v.encode() creator = dataset.attrs['creator'] if h5py3 else \ dataset.attrs['creator'].decode() - dataset.attrs['creator'] = f"damask.Result.{creator} v{damask.version}" if h5py3 else \ - f"damask.Result.{creator} v{damask.version}".encode() + dataset.attrs['creator'] = f'damask.Result.{creator} v{damask.version}' if h5py3 else \ + f'damask.Result.{creator} v{damask.version}'.encode() except (OSError,RuntimeError) as err: print(f'Could not add dataset: {err}.') diff --git a/python/damask/util.py b/python/damask/util.py index 8e1c6a0f8..3794ab751 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -59,9 +59,9 @@ def srepr(arg,glue = '\n'): Glue used for joining operation. Defaults to \n. """ - if (not hasattr(arg, "strip") and - (hasattr(arg, "__getitem__") or - hasattr(arg, "__iter__"))): + if (not hasattr(arg, 'strip') and + (hasattr(arg, '__getitem__') or + hasattr(arg, '__iter__'))): return glue.join(str(x) for x in arg) return arg if isinstance(arg,str) else repr(arg) From 885aeb62e58f954c57c0772b7fd08b76df889b49 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 3 Apr 2021 08:58:22 +0200 Subject: [PATCH 098/219] geometry0 itself is useful can be combined with 'place' if in-memory VTK is required for spatial operations --- python/damask/_result.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index b3e803972..fcf178f44 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -530,6 +530,17 @@ class Result: with h5py.File(self.fname,'r') as f: return f['geometry/x_n'][()] + @property + def geometry0(self): + if self.structured: + return VTK.from_rectilinear_grid(self.cells,self.size,self.origin) + else: + with h5py.File(self.fname,'r') as f: + return VTK.from_unstructured_grid(f['/geometry/x_n'][()], + f['/geometry/T_c'][()]-1, + f['/geometry/T_c'].attrs['VTK_TYPE'] if h5py3 else \ + f['/geometry/T_c'].attrs['VTK_TYPE'].decode()) + @staticmethod def _add_absolute(x): @@ -1267,15 +1278,7 @@ class Result: """ if mode.lower()=='cell': - - if self.structured: - v = VTK.from_rectilinear_grid(self.cells,self.size,self.origin) - else: - with h5py.File(self.fname,'r') as f: - v = VTK.from_unstructured_grid(f['/geometry/x_n'][()], - f['/geometry/T_c'][()]-1, - f['/geometry/T_c'].attrs['VTK_TYPE'] if h5py3 else \ - f['/geometry/T_c'].attrs['VTK_TYPE'].decode()) + v = self.geometry0 elif mode.lower()=='point': v = VTK.from_poly_data(self.coordinates0_point) From 27f2e3b26e4d555af009912d9f0d1b600eb35c83 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 3 Apr 2021 11:08:22 +0200 Subject: [PATCH 099/219] avoid random order when using sets --- python/damask/_result.py | 67 +++++++++++++++++++++------------------- python/damask/util.py | 6 ++++ 2 files changed, 41 insertions(+), 32 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index fcf178f44..f0f48e614 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -25,11 +25,27 @@ from . import util h5py3 = h5py.__version__[0] == '3' + def _read(dataset): metadata = {k:(v if h5py3 else v.decode()) for k,v in dataset.attrs.items()} dtype = np.dtype(dataset.dtype,metadata=metadata) return np.array(dataset,dtype=dtype) +def _match(requested,existing): + def flatten_list(list_of_lists): + return [e for e_ in list_of_lists for e in e_] + + if requested is True: + requested = '*' + elif requested is False or requested is None: + requested = [] + + requested_ = requested if hasattr(requested,'__iter__') and not isinstance(requested,str) else \ + [requested] + + return sorted(set(flatten_list([glob.fnmatch.filter(existing,r) for r in requested_])), + key=util.natural_sort) + class Result: """ @@ -70,10 +86,9 @@ class Result: self.origin = f['geometry'].attrs['origin'] r=re.compile('inc[0-9]+' if self.version_minor < 12 else 'increment_[0-9]+') - increments_unsorted = {int(i[10:]):i for i in f.keys() if r.match(i)} - self.increments = [increments_unsorted[i] for i in sorted(increments_unsorted)] - self.times = [round(f[i].attrs['time/s'],12) for i in self.increments] if self.version_minor < 12 else \ - [round(f[i].attrs['t/s'],12) for i in self.increments] + self.increments = sorted([i for i in f.keys() if r.match(i)],key=util.natural_sort) + self.times = [round(f[i].attrs['time/s'],12) for i in self.increments] if self.version_minor < 12 else \ + [round(f[i].attrs['t/s'],12) for i in self.increments] grp = 'mapping' if self.version_minor < 12 else 'cell_to' @@ -81,15 +96,17 @@ class Result: self.homogenizations = [m.decode() for m in np.unique(f[f'{grp}/homogenization'] ['Name' if self.version_minor < 12 else 'label'])] + self.homogenizations = sorted(self.homogenizations,key=util.natural_sort) self.phases = [c.decode() for c in np.unique(f[f'{grp}/phase'] ['Name' if self.version_minor < 12 else 'label'])] + self.phases = sorted(self.phases,key=util.natural_sort) self.fields = [] for c in self.phases: self.fields += f['/'.join([self.increments[0],'phase',c])].keys() for m in self.homogenizations: self.fields += f['/'.join([self.increments[0],'homogenization',m])].keys() - self.fields = list(set(self.fields)) # make unique + self.fields = sorted(set(self.fields),key=util.natural_sort) # make unique self.visible = {'increments': self.increments, 'phases': self.phases, @@ -135,14 +152,10 @@ class Result: True is equivalent to [*], False is equivalent to []. """ - def natural_sort(key): - convert = lambda text: int(text) if text.isdigit() else text - return [ convert(c) for c in re.split('([0-9]+)', key) ] - # allow True/False and string arguments if datasets is True: - datasets = ['*'] - elif datasets is False: + datasets = '*' + elif datasets is False or datasets is None: datasets = [] choice = datasets if hasattr(datasets,'__iter__') and not isinstance(datasets,str) else \ [datasets] @@ -166,19 +179,17 @@ class Result: elif np.isclose(c,self.times[idx+1]): choice.append(self.increments[idx+1]) - valid = [e for e_ in [glob.fnmatch.filter(getattr(self,what),s) for s in choice] for e in e_] + valid = _match(choice,getattr(self,what)) existing = set(self.visible[what]) if action == 'set': - self.visible[what] = valid + self.visible[what] = sorted(set(valid), key=util.natural_sort) elif action == 'add': add = existing.union(valid) - add_sorted = sorted(add, key=natural_sort) - self.visible[what] = add_sorted + self.visible[what] = sorted(add, key=util.natural_sort) elif action == 'del': diff = existing.difference(valid) - diff_sorted = sorted(diff, key=natural_sort) - self.visible[what] = diff_sorted + self.visible[what] = sorted(diff, key=util.natural_sort) def _get_attribute(self,path,attr): @@ -1285,7 +1296,6 @@ class Result: ln = 3 if self.version_minor < 12 else 10 # compatibility hack N_digits = int(np.floor(np.log10(max(1,int(self.increments[-1][ln:])))))+1 - output_ = set([output] if isinstance(output,str) else output) constituents_ = constituents if isinstance(constituents,Iterable) else \ (range(self.N_constituents) if constituents is None else [constituents]) @@ -1322,8 +1332,7 @@ class Result: if field not in f['/'.join((inc,ty,label))].keys(): continue outs = {} - for out in f['/'.join((inc,ty,label,field))].keys() if '*' in output_ else \ - output_.intersection(f['/'.join((inc,ty,label,field))].keys()): + for out in _match(output,f['/'.join((inc,ty,label,field))].keys()): data = ma.array(_read(f['/'.join((inc,ty,label,field,out))])) if ty == 'phase': @@ -1375,23 +1384,20 @@ class Result: """ r = {} - output_ = set([output] if isinstance(output,str) else output) with h5py.File(self.fname,'r') as f: for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{},'geometry':{}} - for out in f['/'.join((inc,'geometry'))].keys() if '*' in output_ else \ - output_.intersection(f['/'.join((inc,'geometry'))].keys()): + for out in _match(output,f['/'.join((inc,'geometry'))].keys()): r[inc]['geometry'][out] = _read(f['/'.join((inc,'geometry',out))]) for ty in ['phase','homogenization']: for label in self.visible[ty+'s']: r[inc][ty][label] = {} - for field in set(self.visible['fields']).union(f['/'.join((inc,ty,label))].keys()): + for field in _match(self.visible['fields'],f['/'.join((inc,ty,label))].keys()): r[inc][ty][label][field] = {} - for out in f['/'.join((inc,ty,label,field))].keys() if '*' in output_ else \ - output_.intersection(f['/'.join((inc,ty,label,field))].keys()): + for out in _match(output,f['/'.join((inc,ty,label,field))].keys()): r[inc][ty][label][field][out] = _read(f['/'.join((inc,ty,label,field,out))]) if prune: r = util.dict_prune(r) @@ -1435,7 +1441,6 @@ class Result: """ r = {} - output_ = set([output] if isinstance(output,str) else output) constituents_ = constituents if isinstance(constituents,Iterable) else \ (range(self.N_constituents) if constituents is None else [constituents]) @@ -1464,18 +1469,16 @@ class Result: for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{},'geometry':{}} - for out in f['/'.join((inc,'geometry'))].keys() if '*' in output_ else \ - output_.intersection(f['/'.join((inc,'geometry'))].keys()): + for out in _match(output,f['/'.join((inc,'geometry'))].keys()): r[inc]['geometry'][out] = _read(f['/'.join((inc,'geometry',out))]) for ty in ['phase','homogenization']: for label in self.visible[ty+'s']: - for field in set(self.visible['fields']).union(f['/'.join((inc,ty,label))].keys()): + for field in _match(self.visible['fields'],f['/'.join((inc,ty,label))].keys()): if field not in r[inc][ty].keys(): r[inc][ty][field] = {} - for out in f['/'.join((inc,ty,label,field))].keys() if '*' in output_ else \ - output_.intersection(f['/'.join((inc,ty,label,field))].keys()): + for out in _match(output,f['/'.join((inc,ty,label,field))].keys()): data = ma.array(_read(f['/'.join((inc,ty,label,field,out))])) if ty == 'phase': diff --git a/python/damask/util.py b/python/damask/util.py index 3794ab751..9c99675f3 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -17,6 +17,7 @@ __all__=[ 'srepr', 'emph','deemph','warn','strikeout', 'execute', + 'natural_sort', 'show_progress', 'scale_to_coprime', 'project_stereographic', @@ -113,6 +114,11 @@ def execute(cmd,wd='./',env=None): return process.stdout, process.stderr +def natural_sort(key): + convert = lambda text: int(text) if text.isdigit() else text + return [ convert(c) for c in re.split('([0-9]+)', key) ] + + def show_progress(iterable,N_iter=None,prefix='',bar_length=50): """ Decorate a loop with a status bar. From 6f3dc80079117edd2c63d315f85045077c51f32f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 3 Apr 2021 13:11:20 +0200 Subject: [PATCH 100/219] simplified/using new functionality --- python/damask/_result.py | 31 ++++---- python/damask/util.py | 2 +- python/tests/test_Result.py | 154 +++++++++++++----------------------- 3 files changed, 72 insertions(+), 115 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index f0f48e614..5c6a328f5 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -419,25 +419,22 @@ class Result: un = 'Unit' if self.version_minor < 12 else 'unit' message = '' with h5py.File(self.fname,'r') as f: - for i in self.iterate('increments'): + for i in self.visible['increments']: message += f'\n{i} ({self.times[self.increments.index(i)]}s)\n' for o,p in zip(['phases','homogenizations'],['fields','fields']): message += f' {o[:-1]}\n' - for oo in self.iterate(o): + for oo in self.visible[o]: message += f' {oo}\n' - for pp in self.iterate(p): + for pp in self.visible[p]: message += f' {pp}\n' - group = '/'.join([i,o[:-1],oo,pp]) # o[:-1]: plural/singular issue - for d in f[group].keys(): - try: - dataset = f['/'.join([group,d])] - unit = f" / {dataset.attrs[un]}" if h5py3 else \ - f" / {dataset.attrs[un].decode()}" - description = dataset.attrs[de] if h5py3 else \ - dataset.attrs[de].decode() - message += f' {d}{unit}: {description}\n' - except KeyError: - pass + for d in f['/'.join([i,o[:-1],oo,pp])].keys(): + dataset = f['/'.join([i,o[:-1],oo,pp,d])] + unit = f' / {dataset.attrs[un]}' if h5py3 else \ + f' / {dataset.attrs[un].decode()}' + description = dataset.attrs[de] if h5py3 else \ + dataset.attrs[de].decode() + message += f' {d}{unit}: {description}\n' + return message @@ -445,7 +442,7 @@ class Result: """Return the location of all active datasets with given label.""" path = [] with h5py.File(self.fname,'r') as f: - for i in self.iterate('increments'): + for i in self.visible['increments']: k = '/'.join([i,'geometry',label]) try: f[k] @@ -453,8 +450,8 @@ class Result: except KeyError: pass for o,p in zip(['phases','homogenizations'],['fields','fields']): - for oo in self.iterate(o): - for pp in self.iterate(p): + for oo in self.visible[o]: + for pp in self.visible[p]: k = '/'.join([i,o[:-1],oo,pp,label]) try: f[k] diff --git a/python/damask/util.py b/python/damask/util.py index 9c99675f3..59fcd6953 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -399,7 +399,7 @@ def DREAM3D_cell_data_group(fname): """ base_group = DREAM3D_base_group(fname) with h5py.File(fname,'r') as f: - cells = tuple(f[os.path.join(base_group,'_SIMPL_GEOMETRY','DIMENSIONS')][()][::-1]) + cells = tuple(f['/'.join((base_group,'_SIMPL_GEOMETRY','DIMENSIONS'))][()][::-1]) cell_data_group = f[base_group].visititems(lambda path,obj: path.split('/')[0] \ if isinstance(obj,h5py._hl.dataset.Dataset) and np.shape(obj)[:-1] == cells \ else None) diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 293ace66c..94f0d6f1a 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -59,39 +59,39 @@ class TestResult: def test_view_all(self,default): default.view('increments',True) - a = default.get_dataset_location('F') + a = default.read('F') + default.view('increments','*') - b = default.get_dataset_location('F') + assert dict_equal(a,default.read('F')) default.view('increments',default.increments_in_range(0,np.iinfo(int).max)) - c = default.get_dataset_location('F') + assert dict_equal(a,default.read('F')) default.view('times',True) - d = default.get_dataset_location('F') + assert dict_equal(a,default.read('F')) default.view('times','*') - e = default.get_dataset_location('F') + assert dict_equal(a,default.read('F')) default.view('times',default.times_in_range(0.0,np.inf)) - f = default.get_dataset_location('F') - assert a == b == c == d == e ==f + assert dict_equal(a,default.read('F')) @pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations def test_view_none(self,default,what): default.view(what,False) - a = default.get_dataset_location('F') + a = default.read('F') default.view(what,[]) - b = default.get_dataset_location('F') + b = default.read('F') - assert a == b == [] + assert a == b == {} @pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations def test_view_more(self,default,what): default.view(what,False) default.view_more(what,'*') - a = default.get_dataset_location('F') + a = default.read('F') default.view(what,True) - b = default.get_dataset_location('F') + b = default.read('F') - assert a == b + assert dict_equal(a,b) @pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations def test_view_less(self,default,what): @@ -110,10 +110,8 @@ class TestResult: def test_add_absolute(self,default): default.add_absolute('F_e') - loc = {'F_e': default.get_dataset_location('F_e'), - '|F_e|': default.get_dataset_location('|F_e|')} - in_memory = np.abs(default.read_dataset(loc['F_e'],0)) - in_file = default.read_dataset(loc['|F_e|'],0) + in_memory = np.abs(default.place('F_e')) + in_file = default.place('|F_e|') assert np.allclose(in_memory,in_file) @pytest.mark.parametrize('mode',['direct','function']) @@ -129,56 +127,42 @@ class TestResult: default.enable_user_function(f.my_func) default.add_calculation('x','my_func(#F#)','-','my notes') - loc = {'F': default.get_dataset_location('F'), - 'x': default.get_dataset_location('x')} - in_memory = 2.0*np.abs(default.read_dataset(loc['F'],0))-1.0 - in_file = default.read_dataset(loc['x'],0) + in_memory = 2.0*np.abs(default.place('F'))-1.0 + in_file = default.place('x') assert np.allclose(in_memory,in_file) def test_add_stress_Cauchy(self,default): default.add_stress_Cauchy('P','F') - loc = {'F': default.get_dataset_location('F'), - 'P': default.get_dataset_location('P'), - 'sigma':default.get_dataset_location('sigma')} - in_memory = mechanics.stress_Cauchy(default.read_dataset(loc['P'],0), - default.read_dataset(loc['F'],0)) - in_file = default.read_dataset(loc['sigma'],0) + in_memory = mechanics.stress_Cauchy(default.place('P'), default.place('F')) + in_file = default.place('sigma') assert np.allclose(in_memory,in_file) def test_add_determinant(self,default): default.add_determinant('P') - loc = {'P': default.get_dataset_location('P'), - 'det(P)':default.get_dataset_location('det(P)')} - in_memory = np.linalg.det(default.read_dataset(loc['P'],0)).reshape(-1,1) - in_file = default.read_dataset(loc['det(P)'],0) + in_memory = np.linalg.det(default.place('P')) + in_file = default.place('det(P)') assert np.allclose(in_memory,in_file) def test_add_deviator(self,default): default.add_deviator('P') - loc = {'P' :default.get_dataset_location('P'), - 's_P':default.get_dataset_location('s_P')} - in_memory = tensor.deviatoric(default.read_dataset(loc['P'],0)) - in_file = default.read_dataset(loc['s_P'],0) + in_memory = tensor.deviatoric(default.place('P')) + in_file = default.place('s_P') assert np.allclose(in_memory,in_file) @pytest.mark.parametrize('eigenvalue,function',[('max',np.amax),('min',np.amin)]) def test_add_eigenvalue(self,default,eigenvalue,function): default.add_stress_Cauchy('P','F') default.add_eigenvalue('sigma',eigenvalue) - loc = {'sigma' :default.get_dataset_location('sigma'), - 'lambda':default.get_dataset_location(f'lambda_{eigenvalue}(sigma)')} - in_memory = function(tensor.eigenvalues(default.read_dataset(loc['sigma'],0)),axis=1,keepdims=True) - in_file = default.read_dataset(loc['lambda'],0) + in_memory = function(tensor.eigenvalues(default.place('sigma')),axis=1) + in_file = default.place(f'lambda_{eigenvalue}(sigma)') assert np.allclose(in_memory,in_file) @pytest.mark.parametrize('eigenvalue,idx',[('max',2),('mid',1),('min',0)]) def test_add_eigenvector(self,default,eigenvalue,idx): default.add_stress_Cauchy('P','F') default.add_eigenvector('sigma',eigenvalue) - loc = {'sigma' :default.get_dataset_location('sigma'), - 'v(sigma)':default.get_dataset_location(f'v_{eigenvalue}(sigma)')} - in_memory = tensor.eigenvectors(default.read_dataset(loc['sigma'],0))[:,idx] - in_file = default.read_dataset(loc['v(sigma)'],0) + in_memory = tensor.eigenvectors(default.place('sigma'))[:,idx] + in_file = default.place(f'v_{eigenvalue}(sigma)') assert np.allclose(in_memory,in_file) @pytest.mark.parametrize('d',[[1,0,0],[0,1,0],[0,0,1]]) @@ -186,7 +170,7 @@ class TestResult: default.add_IPF_color(d,'O') loc = {'O': default.get_dataset_location('O'), 'color': default.get_dataset_location('IPFcolor_[{} {} {}]'.format(*d))} - qu = default.read_dataset(loc['O']).view(np.double).squeeze() + qu = default.read_dataset(loc['O']) crystal_structure = default._get_attribute(default.get_dataset_location('O')[0],'lattice') c = Orientation(rotation=qu,lattice=crystal_structure) in_memory = np.uint8(c.IPF_color(np.array(d))*255) @@ -196,10 +180,8 @@ class TestResult: def test_add_maximum_shear(self,default): default.add_stress_Cauchy('P','F') default.add_maximum_shear('sigma') - loc = {'sigma' :default.get_dataset_location('sigma'), - 'max_shear(sigma)':default.get_dataset_location('max_shear(sigma)')} - in_memory = mechanics.maximum_shear(default.read_dataset(loc['sigma'],0)).reshape(-1,1) - in_file = default.read_dataset(loc['max_shear(sigma)'],0) + in_memory = mechanics.maximum_shear(default.place('sigma')) + in_file = default.place('max_shear(sigma)') assert np.allclose(in_memory,in_file) def test_add_Mises_strain(self,default): @@ -208,19 +190,15 @@ class TestResult: default.add_strain('F',t,m) label = f'epsilon_{t}^{m}(F)' default.add_equivalent_Mises(label) - loc = {label :default.get_dataset_location(label), - label+'_vM':default.get_dataset_location(label+'_vM')} - in_memory = mechanics.equivalent_strain_Mises(default.read_dataset(loc[label],0)).reshape(-1,1) - in_file = default.read_dataset(loc[label+'_vM'],0) + in_memory = mechanics.equivalent_strain_Mises(default.place(label)) + in_file = default.place(label+'_vM') assert np.allclose(in_memory,in_file) def test_add_Mises_stress(self,default): default.add_stress_Cauchy('P','F') default.add_equivalent_Mises('sigma') - loc = {'sigma' :default.get_dataset_location('sigma'), - 'sigma_vM':default.get_dataset_location('sigma_vM')} - in_memory = mechanics.equivalent_stress_Mises(default.read_dataset(loc['sigma'],0)).reshape(-1,1) - in_file = default.read_dataset(loc['sigma_vM'],0) + in_memory = mechanics.equivalent_stress_Mises(default.place('sigma')) + in_file = default.place('sigma_vM') assert np.allclose(in_memory,in_file) def test_add_Mises_invalid(self,default): @@ -235,26 +213,20 @@ class TestResult: default.add_calculation('sigma_x','#sigma#',unit='x') default.add_equivalent_Mises('sigma_y',kind='strain') default.add_equivalent_Mises('sigma_x',kind='stress') - loc = {'y' :default.get_dataset_location('sigma_y_vM'), - 'x' :default.get_dataset_location('sigma_x_vM')} - assert not np.allclose(default.read_dataset(loc['y'],0),default.read_dataset(loc['x'],0)) + assert not np.allclose(default.place('sigma_y_vM'),default.place('sigma_x_vM')) - def test_add_norm(self,default): - default.add_norm('F',1) - loc = {'F': default.get_dataset_location('F'), - '|F|_1':default.get_dataset_location('|F|_1')} - in_memory = np.linalg.norm(default.read_dataset(loc['F'],0),ord=1,axis=(1,2),keepdims=True) - in_file = default.read_dataset(loc['|F|_1'],0) + @pytest.mark.parametrize('ord',[1,2]) + @pytest.mark.parametrize('dataset,axis',[('F',(1,2)),('xi_sl',(1,))]) + def test_add_norm(self,default,ord,dataset,axis): + default.add_norm(dataset,ord) + in_memory = np.linalg.norm(default.place(dataset),ord=ord,axis=axis,keepdims=True) + in_file = default.place(f'|{dataset}|_{ord}') assert np.allclose(in_memory,in_file) def test_add_stress_second_Piola_Kirchhoff(self,default): default.add_stress_second_Piola_Kirchhoff('P','F') - loc = {'F':default.get_dataset_location('F'), - 'P':default.get_dataset_location('P'), - 'S':default.get_dataset_location('S')} - in_memory = mechanics.stress_second_Piola_Kirchhoff(default.read_dataset(loc['P'],0), - default.read_dataset(loc['F'],0)) - in_file = default.read_dataset(loc['S'],0) + in_memory = mechanics.stress_second_Piola_Kirchhoff(default.place('P'),default.place('F')) + in_file = default.place('S') assert np.allclose(in_memory,in_file) @pytest.mark.skip(reason='requires rework of lattice.f90') @@ -262,30 +234,24 @@ class TestResult: def test_add_pole(self,default,polar): pole = np.array([1.,0.,0.]) default.add_pole('O',pole,polar) - loc = {'O': default.get_dataset_location('O'), - 'pole': default.get_dataset_location('p^{}_[1 0 0)'.format(u'rφ' if polar else 'xy'))} - rot = Rotation(default.read_dataset(loc['O']).view(np.double)) + rot = Rotation(default.place('O')) rotated_pole = rot * np.broadcast_to(pole,rot.shape+(3,)) xy = rotated_pole[:,0:2]/(1.+abs(pole[2])) in_memory = xy if not polar else \ np.block([np.sqrt(xy[:,0:1]*xy[:,0:1]+xy[:,1:2]*xy[:,1:2]),np.arctan2(xy[:,1:2],xy[:,0:1])]) - in_file = default.read_dataset(loc['pole']) + in_file = default.place('p^{}_[1 0 0)'.format(u'rφ' if polar else 'xy')) assert np.allclose(in_memory,in_file) def test_add_rotation(self,default): default.add_rotation('F') - loc = {'F': default.get_dataset_location('F'), - 'R(F)': default.get_dataset_location('R(F)')} - in_memory = mechanics.rotation(default.read_dataset(loc['F'],0)).as_matrix() - in_file = default.read_dataset(loc['R(F)'],0) + in_memory = mechanics.rotation(default.place('F')).as_matrix() + in_file = default.place('R(F)') assert np.allclose(in_memory,in_file) def test_add_spherical(self,default): default.add_spherical('P') - loc = {'P': default.get_dataset_location('P'), - 'p_P': default.get_dataset_location('p_P')} - in_memory = tensor.spherical(default.read_dataset(loc['P'],0),False).reshape(-1,1) - in_file = default.read_dataset(loc['p_P'],0) + in_memory = tensor.spherical(default.place('P'),False) + in_file = default.place('p_P') assert np.allclose(in_memory,in_file) def test_add_strain(self,default): @@ -293,26 +259,20 @@ class TestResult: m = np.random.random()*2.0 - 1.0 default.add_strain('F',t,m) label = f'epsilon_{t}^{m}(F)' - loc = {'F': default.get_dataset_location('F'), - label: default.get_dataset_location(label)} - in_memory = mechanics.strain(default.read_dataset(loc['F'],0),t,m) - in_file = default.read_dataset(loc[label],0) + in_memory = mechanics.strain(default.place('F'),t,m) + in_file = default.place(label) assert np.allclose(in_memory,in_file) def test_add_stretch_right(self,default): default.add_stretch_tensor('F','U') - loc = {'F': default.get_dataset_location('F'), - 'U(F)': default.get_dataset_location('U(F)')} - in_memory = mechanics.stretch_right(default.read_dataset(loc['F'],0)) - in_file = default.read_dataset(loc['U(F)'],0) + in_memory = mechanics.stretch_right(default.place('F')) + in_file = default.place('U(F)') assert np.allclose(in_memory,in_file) def test_add_stretch_left(self,default): default.add_stretch_tensor('F','V') - loc = {'F': default.get_dataset_location('F'), - 'V(F)': default.get_dataset_location('V(F)')} - in_memory = mechanics.stretch_left(default.read_dataset(loc['F'],0)) - in_file = default.read_dataset(loc['V(F)'],0) + in_memory = mechanics.stretch_left(default.place('F')) + in_file = default.place('V(F)') assert np.allclose(in_memory,in_file) def test_add_invalid(self,default): @@ -358,10 +318,10 @@ class TestResult: @pytest.mark.parametrize('allowed',['off','on']) def test_rename(self,default,allowed): if allowed == 'on': - F = default.read_dataset(default.get_dataset_location('F')) + F = default.place('F') default.allow_modification() default.rename('F','new_name') - assert np.all(F == default.read_dataset(default.get_dataset_location('new_name'))) + assert np.all(F == default.place('new_name')) default.disallow_modification() with pytest.raises(PermissionError): From 09beb8f38cb0dd06bf471aca2d4f01aedc9bcf7a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 3 Apr 2021 16:44:38 +0200 Subject: [PATCH 101/219] white space adjustments --- src/YAML_types.f90 | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index b294f9ba1..3d83831e6 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -123,15 +123,15 @@ module YAML_types procedure :: asFormattedString => tList_asFormattedString procedure :: append => tList_append procedure :: & - as1dFloat => tList_as1dFloat + as1dFloat => tList_as1dFloat procedure :: & - as2dFloat => tList_as2dFloat + as2dFloat => tList_as2dFloat procedure :: & - as1dInt => tList_as1dInt + as1dInt => tList_as1dInt procedure :: & - as1dBool => tList_as1dBool + as1dBool => tList_as1dBool procedure :: & - as1dString => tList_as1dString + as1dString => tList_as1dString final :: tList_finalize end type tList @@ -329,8 +329,8 @@ end subroutine tScalar_assign__ !-------------------------------------------------------------------------------------------------- function tNode_asScalar(self) result(scalar) - class(tNode), intent(in), target :: self - class(tScalar), pointer :: scalar + class(tNode), intent(in), target :: self + class(tScalar), pointer :: scalar select type(self) class is(tScalar) @@ -345,8 +345,8 @@ end function tNode_asScalar !-------------------------------------------------------------------------------------------------- function tNode_asList(self) result(list) - class(tNode), intent(in), target :: self - class(tList), pointer :: list + class(tNode), intent(in), target :: self + class(tList), pointer :: list select type(self) class is(tList) @@ -361,8 +361,8 @@ end function tNode_asList !-------------------------------------------------------------------------------------------------- function tNode_asDict(self) result(dict) - class(tNode), intent(in), target :: self - class(tDict), pointer :: dict + class(tNode), intent(in), target :: self + class(tDict), pointer :: dict select type(self) class is(tDict) @@ -720,7 +720,6 @@ function tNode_get_byKey_asFloat(self,k,defaultVal) result(nodeAsFloat) class(tNode), pointer :: node type(tScalar), pointer :: scalar - character(len=:), allocatable :: str if (self%contains(k)) then node => self%get(k) From 857a990a0ef3590560184e059b6a9f6b540d0c84 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 3 Apr 2021 20:39:07 +0200 Subject: [PATCH 102/219] avoid long lines --- src/mesh/DAMASK_mesh.f90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mesh/DAMASK_mesh.f90 b/src/mesh/DAMASK_mesh.f90 index 5ef0f7a36..e19aee822 100644 --- a/src/mesh/DAMASK_mesh.f90 +++ b/src/mesh/DAMASK_mesh.f90 @@ -89,7 +89,8 @@ program DAMASK_mesh if (maxCutBack < 0) call IO_error(301,ext_msg='maxCutBack') ! reading basic information from load case file and allocate data structure containing load cases - call DMGetDimension(geomMesh,dimPlex,ierr); CHKERRA(ierr) !< dimension of mesh (2D or 3D) + call DMGetDimension(geomMesh,dimPlex,ierr) !< dimension of mesh (2D or 3D) + CHKERRA(ierr) nActiveFields = 1 allocate(solres(nActiveFields)) From 7371c421d4f5b03395fd9d01a7471415d0ef60bd Mon Sep 17 00:00:00 2001 From: Test User Date: Sat, 3 Apr 2021 22:22:58 +0200 Subject: [PATCH 103/219] [skip ci] updated version information after successful test of v3.0.0-alpha2-687-g857a990a0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0c9d33075..d816b70f2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-673-g0c08c9753 +v3.0.0-alpha2-687-g857a990a0 From 6fef46539e88cee396abc4b28047d130b1546b69 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 4 Apr 2021 12:27:39 +0200 Subject: [PATCH 104/219] standard names --- python/damask/_result.py | 60 +++++++++++++--------------------------- 1 file changed, 19 insertions(+), 41 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 5c6a328f5..4c5b05f73 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -366,49 +366,27 @@ class Result: Return groups that contain all requested datasets. Only groups within - - inc*/phase/*/* - - inc*/homogenization/*/* - - inc*/geometry/* + - inc*/phase/*/ + - inc*/homogenization/*/ + - inc*/geometry/ are considered as they contain user-relevant data. Single strings will be treated as list with one entry. - Wild card matching is allowed, but the number of arguments needs to fit. - Parameters ---------- datasets : iterable or str or bool - Examples - -------- - datasets = False matches no group - datasets = True matches all groups - datasets = ['F','P'] matches a group with ['F','P','sigma'] - datasets = ['*','P'] matches a group with ['F','P'] - datasets = ['*'] does not match a group with ['F','P','sigma'] - datasets = ['*','*'] does not match a group with ['F','P','sigma'] - datasets = ['*','*','*'] matches a group with ['F','P','sigma'] - """ - if datasets is False: return [] - - sets = datasets if isinstance(datasets,bool) or (hasattr(datasets,'__iter__') and not isinstance(datasets,str)) else \ - [datasets] - groups = [] with h5py.File(self.fname,'r') as f: - for i in self.iterate('increments'): - for o,p in zip(['phases','homogenizations'],['fields','fields']): - for oo in self.iterate(o): - for pp in self.iterate(p): - group = '/'.join([i,o[:-1],oo,pp]) # o[:-1]: plural/singular issue - if sets is True: - groups.append(group) - else: - if group in f.keys(): - match = [e for e_ in [glob.fnmatch.filter(f[group].keys(),s) for s in sets] for e in e_] - if len(set(match)) == len(sets): groups.append(group) + for inc in self.visible['increments']: + for ty in ['phases','homogenizations']: + for label in self.visible[ty]: + for field in self.visible['fields']: + group = '/'.join([inc,ty[:-1],label,field]) + if set(group) == set(datasets): groups.append(group) return groups @@ -419,16 +397,16 @@ class Result: un = 'Unit' if self.version_minor < 12 else 'unit' message = '' with h5py.File(self.fname,'r') as f: - for i in self.visible['increments']: - message += f'\n{i} ({self.times[self.increments.index(i)]}s)\n' - for o,p in zip(['phases','homogenizations'],['fields','fields']): - message += f' {o[:-1]}\n' - for oo in self.visible[o]: - message += f' {oo}\n' - for pp in self.visible[p]: - message += f' {pp}\n' - for d in f['/'.join([i,o[:-1],oo,pp])].keys(): - dataset = f['/'.join([i,o[:-1],oo,pp,d])] + for inc in self.visible['increments']: + message += f'\n{inc} ({self.times[self.increments.index(inc)]}s)\n' + for ty in ['phases','homogenizations']: + message += f' {ty[:-1]}\n' + for label in self.visible[ty]: + message += f' {label}\n' + for field in self.visible['fields']: + message += f' {field}\n' + for d in f['/'.join([inc,ty[:-1],label,field])].keys(): + dataset = f['/'.join([inc,ty[:-1],label,field,d])] unit = f' / {dataset.attrs[un]}' if h5py3 else \ f' / {dataset.attrs[un].decode()}' description = dataset.attrs[de] if h5py3 else \ From a962777d246be02719592c2eb07f735d1f6c3460 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 4 Apr 2021 13:25:16 +0200 Subject: [PATCH 105/219] avoid code duplication --- python/damask/_result.py | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 4c5b05f73..12ac73901 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -46,6 +46,10 @@ def _match(requested,existing): return sorted(set(flatten_list([glob.fnmatch.filter(existing,r) for r in requested_])), key=util.natural_sort) +def _empty(dataset,N_materialpoints,fill_float,fill_int): + return ma.array(np.empty((N_materialpoints,)+dataset.shape[1:],dataset.dtype), + fill_value = fill_float if dataset.dtype in np.sctypes['float'] else fill_int, + mask = True) class Result: """ @@ -386,7 +390,7 @@ class Result: for label in self.visible[ty]: for field in self.visible['fields']: group = '/'.join([inc,ty[:-1],label,field]) - if set(group) == set(datasets): groups.append(group) + if set(datasets).issubset(f[group].keys()): groups.append(group) return groups @@ -1312,23 +1316,16 @@ class Result: if ty == 'phase': if out+suffixes[0] not in outs.keys(): - container = np.empty((self.N_materialpoints,)+data.shape[1:],data.dtype) - fill_value = fill_float if data.dtype in np.sctypes['float'] else \ - fill_int for c,suffix in zip(constituents_,suffixes): outs[out+suffix] = \ - ma.array(container,fill_value=fill_value,mask=True) + _empty(data,self.N_materialpoints,fill_float,fill_int) for c,suffix in zip(constituents_,suffixes): outs[out+suffix][at_cell_ph[c][label]] = data[in_data_ph[c][label]] if ty == 'homogenization': if out not in outs.keys(): - container = np.empty((self.N_materialpoints,)+data.shape[1:],data.dtype) - fill_value = fill_float if data.dtype in np.sctypes['float'] else \ - fill_int - outs[out] = \ - ma.array(container,fill_value=fill_value,mask=True) + outs[out] = _empty(data,self.N_materialpoints,fill_float,fill_int) outs[out][at_cell_ho[label]] = data[in_data_ho[label]] @@ -1458,23 +1455,17 @@ class Result: if ty == 'phase': if out+suffixes[0] not in r[inc][ty][field].keys(): - container = np.empty((self.N_materialpoints,)+data.shape[1:],data.dtype) - fill_value = fill_float if data.dtype in np.sctypes['float'] else \ - fill_int for c,suffix in zip(constituents_,suffixes): r[inc][ty][field][out+suffix] = \ - ma.array(container,fill_value=fill_value,mask=True) + _empty(data,self.N_materialpoints,fill_float,fill_int) for c,suffix in zip(constituents_,suffixes): r[inc][ty][field][out+suffix][at_cell_ph[c][label]] = data[in_data_ph[c][label]] if ty == 'homogenization': if out not in r[inc][ty][field].keys(): - container = np.empty((self.N_materialpoints,)+data.shape[1:],data.dtype) - fill_value = fill_float if data.dtype in np.sctypes['float'] else \ - fill_int r[inc][ty][field][out] = \ - ma.array(container,fill_value=fill_value,mask=True) + _empty(data,self.N_materialpoints,fill_float,fill_int) r[inc][ty][field][out][at_cell_ho[label]] = data[in_data_ho[label]] From 194b0386c55ef64fb4729cea02557d148fb15b67 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 4 Apr 2021 14:07:50 +0200 Subject: [PATCH 106/219] typo --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3f33842a4..9df1e9330 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -96,7 +96,7 @@ processing: stage: python script: - cd $DAMASKROOT/python - - COLUMS=256 pytest --basetemp=${TESTROOT}/python -v --cov --cov-report=term + - COLUMNS=256 pytest --basetemp=${TESTROOT}/python -v --cov --cov-report=term - coverage report --fail-under=90 except: - master From d78e0085fc6021622c166ed099c7e62de9603b71 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 4 Apr 2021 18:32:17 +0200 Subject: [PATCH 107/219] simplified --- python/damask/_result.py | 39 +++++++++---------------------------- python/tests/test_Result.py | 19 ++++++------------ 2 files changed, 15 insertions(+), 43 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 12ac73901..c79dd0558 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -365,35 +365,6 @@ class Result: raise PermissionError('Rename operation not permitted') - def groups_with_datasets(self,datasets): - """ - Return groups that contain all requested datasets. - - Only groups within - - inc*/phase/*/ - - inc*/homogenization/*/ - - inc*/geometry/ - - are considered as they contain user-relevant data. - Single strings will be treated as list with one entry. - - Parameters - ---------- - datasets : iterable or str or bool - - """ - groups = [] - - with h5py.File(self.fname,'r') as f: - for inc in self.visible['increments']: - for ty in ['phases','homogenizations']: - for label in self.visible[ty]: - for field in self.visible['fields']: - group = '/'.join([inc,ty[:-1],label,field]) - if set(datasets).issubset(f[group].keys()): groups.append(group) - return groups - - def list_data(self): """Return information on all active datasets in the file.""" # compatibility hack @@ -1089,7 +1060,15 @@ class Result: pool = mp.Pool(int(os.environ.get('OMP_NUM_THREADS',1))) lock = mp.Manager().Lock() - groups = self.groups_with_datasets(datasets.values()) + groups = [] + with h5py.File(self.fname,'r') as f: + for inc in self.visible['increments']: + for ty in ['phases','homogenizations']: + for label in self.visible[ty]: + for field in self.visible['fields']: + group = '/'.join([inc,ty[:-1],label,field]) + if set(datasets.values()).issubset(f[group].keys()): groups.append(group) + if len(groups) == 0: print('No matching dataset found, no data was added.') return diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 94f0d6f1a..7fd345012 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -284,13 +284,9 @@ class TestResult: default.view('times',default.times_in_range(0,np.inf)[-1]) default.add_stress_Cauchy() - loc = default.get_dataset_location('sigma') with h5py.File(default.fname,'r') as f: - # h5py3 compatibility - try: - created_first = f[loc[0]].attrs['created'].decode() - except AttributeError: - created_first = f[loc[0]].attrs['created'] + created_first = default.place('sigma').dtype.metadata['created'] + created_first = datetime.strptime(created_first,'%Y-%m-%d %H:%M:%S%z') if overwrite == 'on': @@ -304,16 +300,13 @@ class TestResult: except ValueError: pass with h5py.File(default.fname,'r') as f: - # h5py3 compatibility - try: - created_second = f[loc[0]].attrs['created'].decode() - except AttributeError: - created_second = f[loc[0]].attrs['created'] + created_second = default.place('sigma').dtype.metadata['created'] created_second = datetime.strptime(created_second,'%Y-%m-%d %H:%M:%S%z') + if overwrite == 'on': - assert created_first < created_second and np.allclose(default.read_dataset(loc),311.) + assert created_first < created_second and np.allclose(default.place('sigma'),311.) else: - assert created_first == created_second and not np.allclose(default.read_dataset(loc),311.) + assert created_first == created_second and not np.allclose(default.place('sigma'),311.) @pytest.mark.parametrize('allowed',['off','on']) def test_rename(self,default,allowed): From e1d57f176d057c18f2561fb9d3846b332f2edde2 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 4 Apr 2021 19:05:58 +0200 Subject: [PATCH 108/219] simplifying [] has a special meaning for glob, use () to indicate direction for IPF color. It is anyways the sample direction, not a crystallographic direction --- python/damask/_result.py | 4 ++-- python/tests/test_Result.py | 16 +++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index c79dd0558..b5cb6a35f 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -720,11 +720,11 @@ class Result: return { 'data': np.uint8(o.IPF_color(l)*255), - 'label': 'IPFcolor_[{} {} {}]'.format(*m), + 'label': 'IPFcolor_({} {} {})'.format(*m), 'meta' : { 'unit': '8-bit RGB', 'lattice': q['meta']['lattice'], - 'description': 'Inverse Pole Figure (IPF) colors along sample direction [{} {} {}]'.format(*m), + 'description': 'Inverse Pole Figure (IPF) colors along sample direction ({} {} {})'.format(*m), 'creator': 'add_IPF_color' } } diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 7fd345012..4a597c027 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -97,12 +97,12 @@ class TestResult: def test_view_less(self,default,what): default.view(what,True) default.view_less(what,'*') - a = default.get_dataset_location('F') + a = default.read('F') default.view(what,False) - b = default.get_dataset_location('F') + b = default.read('F') - assert a == b == [] + assert a == b == {} def test_view_invalid(self,default): with pytest.raises(AttributeError): @@ -168,13 +168,11 @@ class TestResult: @pytest.mark.parametrize('d',[[1,0,0],[0,1,0],[0,0,1]]) def test_add_IPF_color(self,default,d): default.add_IPF_color(d,'O') - loc = {'O': default.get_dataset_location('O'), - 'color': default.get_dataset_location('IPFcolor_[{} {} {}]'.format(*d))} - qu = default.read_dataset(loc['O']) - crystal_structure = default._get_attribute(default.get_dataset_location('O')[0],'lattice') + qu = default.place('O') + crystal_structure = qu.dtype.metadata['lattice'] c = Orientation(rotation=qu,lattice=crystal_structure) in_memory = np.uint8(c.IPF_color(np.array(d))*255) - in_file = default.read_dataset(loc['color']) + in_file = default.place('IPFcolor_({} {} {})'.format(*d)) assert np.allclose(in_memory,in_file) def test_add_maximum_shear(self,default): @@ -205,7 +203,7 @@ class TestResult: default.add_stress_Cauchy('P','F') default.add_calculation('sigma_y','#sigma#',unit='y') default.add_equivalent_Mises('sigma_y') - assert default.get_dataset_location('sigma_y_vM') == [] + assert default.read('sigma_y_vM') == {} def test_add_Mises_stress_strain(self,default): default.add_stress_Cauchy('P','F') From 0e5f693feac64f7cd413eaab2ce46c37a18f880c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 4 Apr 2021 19:44:06 +0200 Subject: [PATCH 109/219] untangling --- python/damask/_result.py | 51 +++++++++++++--------------------------- 1 file changed, 16 insertions(+), 35 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index b5cb6a35f..f57277fcb 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1,6 +1,6 @@ import multiprocessing as mp import re -import glob +import fnmatch import os import datetime import xml.etree.ElementTree as ET @@ -43,7 +43,7 @@ def _match(requested,existing): requested_ = requested if hasattr(requested,'__iter__') and not isinstance(requested,str) else \ [requested] - return sorted(set(flatten_list([glob.fnmatch.filter(existing,r) for r in requested_])), + return sorted(set(flatten_list([fnmatch.filter(existing,r) for r in requested_])), key=util.natural_sort) def _empty(dataset,N_materialpoints,fill_float,fill_int): @@ -196,30 +196,6 @@ class Result: self.visible[what] = sorted(diff, key=util.natural_sort) - def _get_attribute(self,path,attr): - """ - Get the attribute of a dataset. - - Parameters - ---------- - Path : str - Path to the dataset. - attr : str - Name of the attribute to get. - - Returns - ------- - attr at path, str or None. - The requested attribute, None if not found. - - """ - with h5py.File(self.fname,'r') as f: - try: - return f[path].attrs[attr] if h5py3 else f[path].attrs[attr].decode() - except KeyError: - return None - - def allow_modification(self): """Allow to overwrite existing data.""" print(util.warn('Warning: Modification of existing datasets allowed!')) @@ -353,17 +329,22 @@ class Result: New name of the dataset. """ - if self._allow_modification: - with h5py.File(self.fname,'a') as f: - for path_old in self.get_dataset_location(name_old): - path_new = '/'.join([os.path.dirname(path_old),name_new]) - f[path_new] = f[path_old] - f[path_new].attrs['Renamed'] = f'Original name: {name_old}' if h5py3 else \ - f'Original name: {name_old}'.encode() - del f[path_old] - else: + if not self._allow_modification: raise PermissionError('Rename operation not permitted') + with h5py.File(self.fname,'a') as f: + for inc in self.visible['increments']: + for ty in ['phases','homogenizations']: + for label in self.visible[ty]: + for field in self.visible['fields']: + path_old = '/'.join([inc,ty[:-1],label,field,name_old]) + path_new = '/'.join([inc,ty[:-1],label,field,name_new]) + if path_old in f.keys(): + f[path_new] = f[path_old] + f[path_new].attrs['renamed'] = f'original name: {name_old}' if h5py3 else \ + f'original name: {name_old}'.encode() + del f[path_old] + def list_data(self): """Return information on all active datasets in the file.""" From 1d6b56346a6371bcbdd5f904fec5fe574b4e6d86 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 4 Apr 2021 20:28:48 +0200 Subject: [PATCH 110/219] use 'view' and standardized calling signature --- python/damask/_result.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index f57277fcb..5f1a746c9 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1096,7 +1096,7 @@ class Result: pool.join() - def save_XDMF(self): + def save_XDMF(self,output='*'): """ Write XDMF file to directly visualize data in DADF5 file. @@ -1139,7 +1139,7 @@ class Result: attributes = [] data_items = [] - for inc in self.increments: + for inc in self.visible['increments']: grid=ET.SubElement(collection,'Grid') grid.attrib = {'GridType': 'Uniform', @@ -1176,12 +1176,11 @@ class Result: 'Dimensions': '{} {} {} 3'.format(*(self.cells+1))} data_items[-1].text=f'{os.path.split(self.fname)[1]}:/{inc}/geometry/u_n' - for o,p in zip(['phases','homogenizations'],['fields','fields']): - for oo in getattr(self,o): - for pp in getattr(self,p): - g = '/'.join([inc,o[:-1],oo,pp]) - for l in f[g]: - name = '/'.join([g,l]) + for ty in ['phases','homogenizations']: + for label in self.visible[ty]: + for field in self.visible['fields']: + for out in _match(output,f['/'.join((inc,ty[:-1],label,field))].keys()): + name = '/'.join([inc,ty[:-1],label,field,out]) shape = f[name].shape[1:] dtype = f[name].dtype From fc409fcf08d69922ab3f37ffbce84bcb02146900 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 4 Apr 2021 22:12:28 +0200 Subject: [PATCH 111/219] 'join' is always linear in time, '+' not --- python/damask/_result.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 5f1a746c9..5139852d4 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -354,20 +354,20 @@ class Result: message = '' with h5py.File(self.fname,'r') as f: for inc in self.visible['increments']: - message += f'\n{inc} ({self.times[self.increments.index(inc)]}s)\n' + ''.join([message,f'\n{inc} ({self.times[self.increments.index(inc)]}s)\n']) for ty in ['phases','homogenizations']: - message += f' {ty[:-1]}\n' + ' '.join([message,f'{ty[:-1]}\n']) for label in self.visible[ty]: - message += f' {label}\n' + ' '.join([message,f'{label}\n']) for field in self.visible['fields']: - message += f' {field}\n' + ' '.join([message,f'{field}\n']) for d in f['/'.join([inc,ty[:-1],label,field])].keys(): dataset = f['/'.join([inc,ty[:-1],label,field,d])] unit = f' / {dataset.attrs[un]}' if h5py3 else \ f' / {dataset.attrs[un].decode()}' description = dataset.attrs[de] if h5py3 else \ dataset.attrs[de].decode() - message += f' {d}{unit}: {description}\n' + ' '.join([message,f'{d}{unit}: {description}\n']) return message From 0ef6e43e62161ab85ecafccdd1df58ff716d69aa Mon Sep 17 00:00:00 2001 From: Test User Date: Sun, 4 Apr 2021 22:35:53 +0200 Subject: [PATCH 112/219] [skip ci] updated version information after successful test of v3.0.0-alpha2-753-g565dab120 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index d816b70f2..e5c6789ca 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-687-g857a990a0 +v3.0.0-alpha2-753-g565dab120 From 62c85db745758c1496408b689c93d9b23b78eff7 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 5 Apr 2021 07:53:19 +0200 Subject: [PATCH 113/219] out of place behavior --- python/damask/_result.py | 192 ++++++++++-------------------------- python/tests/test_Result.py | 74 ++++++-------- 2 files changed, 84 insertions(+), 182 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 5139852d4..008579586 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -2,6 +2,7 @@ import multiprocessing as mp import re import fnmatch import os +import copy import datetime import xml.etree.ElementTree as ET import xml.dom.minidom @@ -27,11 +28,13 @@ h5py3 = h5py.__version__[0] == '3' def _read(dataset): + """Read a dataset and its metadata into a numpy.ndarray.""" metadata = {k:(v if h5py3 else v.decode()) for k,v in dataset.attrs.items()} dtype = np.dtype(dataset.dtype,metadata=metadata) return np.array(dataset,dtype=dtype) def _match(requested,existing): + """Find matches among two sets of labels""" def flatten_list(list_of_lists): return [e for e_ in list_of_lists for e in e_] @@ -47,6 +50,7 @@ def _match(requested,existing): key=util.natural_sort) def _empty(dataset,N_materialpoints,fill_float,fill_int): + """Create empty numpy.ma.MaskedArray.""" return ma.array(np.empty((N_materialpoints,)+dataset.shape[1:],dataset.dtype), fill_value = fill_float if dataset.dtype in np.sctypes['float'] else fill_int, mask = True) @@ -123,17 +127,21 @@ class Result: self._allow_modification = False + def __copy__(self): + """Create deep copy.""" + return copy.deepcopy(self) + + copy = __copy__ + + def __repr__(self): """Show summary of file content.""" visible_increments = self.visible['increments'] - self.view('increments',visible_increments[0:1]) - first = self.list_data() + first = self.view('increments',visible_increments[0:1]).list_data() - self.view('increments',visible_increments[-1:]) - last = '' if len(visible_increments) < 2 else self.list_data() - - self.view('increments',visible_increments) + last = '' if len(visible_increments) < 2 else \ + self.view('increments',visible_increments[-1:]).list_data() in_between = '' if len(visible_increments) < 3 else \ ''.join([f'\n{inc}\n ...\n' for inc in visible_increments[1:-1]]) @@ -186,24 +194,31 @@ class Result: valid = _match(choice,getattr(self,what)) existing = set(self.visible[what]) + dup = self.copy() if action == 'set': - self.visible[what] = sorted(set(valid), key=util.natural_sort) + dup.visible[what] = sorted(set(valid), key=util.natural_sort) elif action == 'add': add = existing.union(valid) - self.visible[what] = sorted(add, key=util.natural_sort) + dup.visible[what] = sorted(add, key=util.natural_sort) elif action == 'del': diff = existing.difference(valid) - self.visible[what] = sorted(diff, key=util.natural_sort) + dup.visible[what] = sorted(diff, key=util.natural_sort) + + return dup def allow_modification(self): """Allow to overwrite existing data.""" print(util.warn('Warning: Modification of existing datasets allowed!')) - self._allow_modification = True + dup = self.copy() + dup._allow_modification = True + return dup def disallow_modification(self): """Disallow to overwrite existing data (default case).""" - self._allow_modification = False + dup = self.copy() + dup._allow_modification = False + return dup def increments_in_range(self,start,end): @@ -247,28 +262,6 @@ class Result: return selected - def iterate(self,what): - """ - Iterate over visible items and view them independently. - - Parameters - ---------- - what : str - Attribute to change (must be from self.visible). - - """ - datasets = self.visible[what] - last_view = datasets.copy() - for dataset in datasets: - if last_view != self.visible[what]: - self._manage_view('set',what,datasets) - raise Exception - self._manage_view('set',what,dataset) - last_view = self.visible[what] - yield dataset - self._manage_view('set',what,datasets) - - def view(self,what,datasets): """ Set view. @@ -279,10 +272,10 @@ class Result: Attribute to change (must be from self.visible). datasets : list of str or bool Name of datasets as list; supports ? and * wildcards. - True is equivalent to [*], False is equivalent to []. + True is equivalent to *, False is equivalent to []. """ - self._manage_view('set',what,datasets) + return self._manage_view('set',what,datasets) def view_more(self,what,datasets): @@ -295,10 +288,10 @@ class Result: Attribute to change (must be from self.visible). datasets : list of str or bool Name of datasets as list; supports ? and * wildcards. - True is equivalent to [*], False is equivalent to []. + True is equivalent to *, False is equivalent to []. """ - self._manage_view('add',what,datasets) + return self._manage_view('add',what,datasets) def view_less(self,what,datasets): @@ -311,10 +304,10 @@ class Result: Attribute to change (must be from self.visible). datasets : list of str or bool Name of datasets as list; supports ? and * wildcards. - True is equivalent to [*], False is equivalent to []. + True is equivalent to *, False is equivalent to []. """ - self._manage_view('del',what,datasets) + return self._manage_view('del',what,datasets) def rename(self,name_old,name_new): @@ -334,11 +327,11 @@ class Result: with h5py.File(self.fname,'a') as f: for inc in self.visible['increments']: - for ty in ['phases','homogenizations']: - for label in self.visible[ty]: + for ty in ['phase','homogenization']: + for label in self.visible[ty+'s']: for field in self.visible['fields']: - path_old = '/'.join([inc,ty[:-1],label,field,name_old]) - path_new = '/'.join([inc,ty[:-1],label,field,name_new]) + path_old = '/'.join([inc,ty,label,field,name_old]) + path_new = '/'.join([inc,ty,label,field,name_new]) if path_old in f.keys(): f[path_new] = f[path_old] f[path_new].attrs['renamed'] = f'original name: {name_old}' if h5py3 else \ @@ -351,48 +344,25 @@ class Result: # compatibility hack de = 'Description' if self.version_minor < 12 else 'description' un = 'Unit' if self.version_minor < 12 else 'unit' - message = '' + msg = '' with h5py.File(self.fname,'r') as f: for inc in self.visible['increments']: - ''.join([message,f'\n{inc} ({self.times[self.increments.index(inc)]}s)\n']) - for ty in ['phases','homogenizations']: - ' '.join([message,f'{ty[:-1]}\n']) - for label in self.visible[ty]: - ' '.join([message,f'{label}\n']) + msg = ''.join([msg,f'\n{inc} ({self.times[self.increments.index(inc)]}s)\n']) + for ty in ['phase','homogenization']: + msg = ' '.join([msg,f'{ty}\n']) + for label in self.visible[ty+'s']: + msg = ' '.join([msg,f'{label}\n']) for field in self.visible['fields']: - ' '.join([message,f'{field}\n']) - for d in f['/'.join([inc,ty[:-1],label,field])].keys(): - dataset = f['/'.join([inc,ty[:-1],label,field,d])] + msg = ' '.join([msg,f'{field}\n']) + for d in f['/'.join([inc,ty,label,field])].keys(): + dataset = f['/'.join([inc,ty,label,field,d])] unit = f' / {dataset.attrs[un]}' if h5py3 else \ f' / {dataset.attrs[un].decode()}' description = dataset.attrs[de] if h5py3 else \ dataset.attrs[de].decode() - ' '.join([message,f'{d}{unit}: {description}\n']) + msg = ' '.join([msg,f'{d}{unit}: {description}\n']) - return message - - - def get_dataset_location(self,label): - """Return the location of all active datasets with given label.""" - path = [] - with h5py.File(self.fname,'r') as f: - for i in self.visible['increments']: - k = '/'.join([i,'geometry',label]) - try: - f[k] - path.append(k) - except KeyError: - pass - for o,p in zip(['phases','homogenizations'],['fields','fields']): - for oo in self.visible[o]: - for pp in self.visible[p]: - k = '/'.join([i,o[:-1],oo,pp,label]) - try: - f[k] - path.append(k) - except KeyError: - pass - return path + return msg def enable_user_function(self,func): @@ -400,60 +370,6 @@ class Result: print(f'Function {func.__name__} enabled in add_calculation.') - def read_dataset(self,path,c=0,plain=False): - """ - Dataset for all points/cells. - - If more than one path is given, the dataset is composed of the individual contributions. - - Parameters - ---------- - path : list of strings - The name of the datasets to consider. - c : int, optional - The constituent to consider. Defaults to 0. - plain: boolean, optional - Convert into plain numpy datatype. - Only relevant for compound datatype, e.g. the orientation. - Defaults to False. - - """ - # compatibility hack - name = 'Name' if self.version_minor < 12 else 'label' - member = 'Position' if self.version_minor < 12 else 'entry' - grp = 'mapping' if self.version_minor < 12 else 'cell_to' - with h5py.File(self.fname,'r') as f: - shape = (self.N_materialpoints,) + np.shape(f[path[0]])[1:] - if len(shape) == 1: shape = shape +(1,) - dataset = np.full(shape,np.nan,dtype=np.dtype(f[path[0]])) - for pa in path: - label = pa.split('/')[2] - - if pa.split('/')[1] == 'geometry': - dataset = np.array(f[pa]) - continue - - p = np.where(f[f'{grp}/phase'][:,c][name] == str.encode(label))[0] - if len(p)>0: - u = (f[f'{grp}/phase'][member][p,c]) - a = np.array(f[pa]) - if len(a.shape) == 1: - a=a.reshape([a.shape[0],1]) - dataset[p,:] = a[u,:] - - p = np.where(f[f'{grp}/homogenization'][name] == str.encode(label))[0] - if len(p)>0: - u = (f[f'{grp}/homogenization'][member][p.tolist()]) - a = np.array(f[pa]) - if len(a.shape) == 1: - a=a.reshape([a.shape[0],1]) - dataset[p,:] = a[u,:] - - if plain and dataset.dtype.names is not None: - return dataset.view(('float64',len(dataset.dtype.names))) - else: - return dataset - @property def coordinates0_point(self): """Return initial coordinates of the cell centers.""" @@ -1044,10 +960,10 @@ class Result: groups = [] with h5py.File(self.fname,'r') as f: for inc in self.visible['increments']: - for ty in ['phases','homogenizations']: - for label in self.visible[ty]: + for ty in ['phase','homogenization']: + for label in self.visible[ty+'s']: for field in self.visible['fields']: - group = '/'.join([inc,ty[:-1],label,field]) + group = '/'.join([inc,ty,label,field]) if set(datasets.values()).issubset(f[group].keys()): groups.append(group) if len(groups) == 0: @@ -1176,11 +1092,11 @@ class Result: 'Dimensions': '{} {} {} 3'.format(*(self.cells+1))} data_items[-1].text=f'{os.path.split(self.fname)[1]}:/{inc}/geometry/u_n' - for ty in ['phases','homogenizations']: - for label in self.visible[ty]: + for ty in ['phase','homogenization']: + for label in self.visible[ty+'s']: for field in self.visible['fields']: - for out in _match(output,f['/'.join((inc,ty[:-1],label,field))].keys()): - name = '/'.join([inc,ty[:-1],label,field,out]) + for out in _match(output,f['/'.join((inc,ty,label,field))].keys()): + name = '/'.join([inc,ty,label,field,out]) shape = f[name].shape[1:] dtype = f[name].dtype diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 4a597c027..32eac281e 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -24,8 +24,7 @@ def default(tmp_path,ref_path): fname = '12grains6x7x8_tensionY.hdf5' shutil.copy(ref_path/fname,tmp_path) f = Result(tmp_path/fname) - f.view('times',20.0) - return f + return f.view('times',20.0) @pytest.fixture def single_phase(tmp_path,ref_path): @@ -58,49 +57,37 @@ class TestResult: def test_view_all(self,default): - default.view('increments',True) - a = default.read('F') + a = default.view('increments',True).read('F') - default.view('increments','*') - assert dict_equal(a,default.read('F')) - default.view('increments',default.increments_in_range(0,np.iinfo(int).max)) - assert dict_equal(a,default.read('F')) + assert dict_equal(a,default.view('increments','*').read('F')) + assert dict_equal(a,default.view('increments',default.increments_in_range(0,np.iinfo(int).max)).read('F')) - default.view('times',True) - assert dict_equal(a,default.read('F')) - default.view('times','*') - assert dict_equal(a,default.read('F')) - default.view('times',default.times_in_range(0.0,np.inf)) - assert dict_equal(a,default.read('F')) + assert dict_equal(a,default.view('times',True).read('F')) + assert dict_equal(a,default.view('times','*').read('F')) + assert dict_equal(a,default.view('times',default.times_in_range(0.0,np.inf)).read('F')) @pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations def test_view_none(self,default,what): - default.view(what,False) - a = default.read('F') - default.view(what,[]) - b = default.read('F') + a = default.view(what,False).read('F') + b = default.view(what,[]).read('F') assert a == b == {} @pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations def test_view_more(self,default,what): - default.view(what,False) - default.view_more(what,'*') - a = default.read('F') + empty = default.view(what,False) - default.view(what,True) - b = default.read('F') + a = empty.view_more(what,'*').read('F') + b = empty.view_more(what,True).read('F') assert dict_equal(a,b) @pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations def test_view_less(self,default,what): - default.view(what,True) - default.view_less(what,'*') - a = default.read('F') + full = default.view(what,True) - default.view(what,False) - b = default.read('F') + a = full.view_less(what,'*').read('F') + b = full.view_less(what,True).read('F') assert a == b == {} @@ -279,41 +266,41 @@ class TestResult: @pytest.mark.parametrize('overwrite',['off','on']) def test_add_overwrite(self,default,overwrite): - default.view('times',default.times_in_range(0,np.inf)[-1]) + last = default.view('times',default.times_in_range(0,np.inf)[-1]) - default.add_stress_Cauchy() - with h5py.File(default.fname,'r') as f: + last.add_stress_Cauchy() + with h5py.File(last.fname,'r') as f: created_first = default.place('sigma').dtype.metadata['created'] created_first = datetime.strptime(created_first,'%Y-%m-%d %H:%M:%S%z') if overwrite == 'on': - default.allow_modification() + last = last.allow_modification() else: - default.disallow_modification() + last = last.disallow_modification() time.sleep(2.) try: - default.add_calculation('sigma','#sigma#*0.0+311.','not the Cauchy stress') + last.add_calculation('sigma','#sigma#*0.0+311.','not the Cauchy stress') except ValueError: pass - with h5py.File(default.fname,'r') as f: - created_second = default.place('sigma').dtype.metadata['created'] + with h5py.File(last.fname,'r') as f: + created_second = last.place('sigma').dtype.metadata['created'] created_second = datetime.strptime(created_second,'%Y-%m-%d %H:%M:%S%z') if overwrite == 'on': - assert created_first < created_second and np.allclose(default.place('sigma'),311.) + assert created_first < created_second and np.allclose(last.place('sigma'),311.) else: - assert created_first == created_second and not np.allclose(default.place('sigma'),311.) + assert created_first == created_second and not np.allclose(last.place('sigma'),311.) @pytest.mark.parametrize('allowed',['off','on']) def test_rename(self,default,allowed): if allowed == 'on': F = default.place('F') - default.allow_modification() + default = default.allow_modification() default.rename('F','new_name') assert np.all(F == default.place('new_name')) - default.disallow_modification() + default = default.disallow_modification() with pytest.raises(PermissionError): default.rename('P','another_new_name') @@ -333,8 +320,7 @@ class TestResult: @pytest.mark.parametrize('fname',['12grains6x7x8_tensionY.hdf5'],ids=range(1)) @pytest.mark.parametrize('inc',[4,0],ids=range(2)) def test_vtk(self,request,tmp_path,ref_path,update,output,fname,inc): - result = Result(ref_path/fname) - result.view('increments',inc) + result = Result(ref_path/fname).view('increments',inc) os.chdir(tmp_path) result.save_VTK(output) fname = fname.split('.')[0]+f'_inc{(inc if type(inc) == int else inc[0]):0>2}.vtr' @@ -387,7 +373,7 @@ class TestResult: def test_read(self,update,request,ref_path,view,output,compress,strip): result = Result(ref_path/'4grains2x4x3_compressionY.hdf5') for key,value in view.items(): - result.view(key,value) + result = result.view(key,value) fname = request.node.name cur = result.read(output,compress,strip) @@ -412,7 +398,7 @@ class TestResult: def test_place(self,update,request,ref_path,view,output,compress,strip,constituents): result = Result(ref_path/'4grains2x4x3_compressionY.hdf5') for key,value in view.items(): - result.view(key,value) + result = result.view(key,value) fname = request.node.name cur = result.place(output,compress,strip,constituents) From 2bfed863ba2c379c1c2f3c65a783af1e86a293da Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 5 Apr 2021 09:04:44 +0200 Subject: [PATCH 114/219] line was to long macro was changed in PETSc 3.15 --- src/mesh/DAMASK_mesh.f90 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mesh/DAMASK_mesh.f90 b/src/mesh/DAMASK_mesh.f90 index ed99d1143..979845484 100644 --- a/src/mesh/DAMASK_mesh.f90 +++ b/src/mesh/DAMASK_mesh.f90 @@ -85,11 +85,12 @@ program DAMASK_mesh stagItMax = num_mesh%get_asInt('maxStaggeredIter',defaultVal=10) maxCutBack = num_mesh%get_asInt('maxCutBack',defaultVal=3) - if (stagItMax < 0) call IO_error(301,ext_msg='maxStaggeredIter') - if (maxCutBack < 0) call IO_error(301,ext_msg='maxCutBack') + if (stagItMax < 0) call IO_error(301,ext_msg='maxStaggeredIter') + if (maxCutBack < 0) call IO_error(301,ext_msg='maxCutBack') ! reading basic information from load case file and allocate data structure containing load cases - call DMGetDimension(geomMesh,dimPlex,ierr); CHKERRA(ierr) !< dimension of mesh (2D or 3D) + call DMGetDimension(geomMesh,dimPlex,ierr) !< dimension of mesh (2D or 3D) + CHKERRA(ierr) nActiveFields = 1 allocate(solres(nActiveFields)) From 9db1ef9ed78990670e55bd2674fee6c1c5cd2be6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 5 Apr 2021 10:29:34 +0200 Subject: [PATCH 115/219] polishing --- PRIVATE | 2 +- python/damask/_result.py | 58 ++++++++++++++++++++----------------- python/damask/_table.py | 3 +- python/tests/test_Result.py | 1 - 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/PRIVATE b/PRIVATE index 4ce1f786d..90ad4d1c4 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 4ce1f786dc2a613f29b2c8681fcf751d6803d38e +Subproject commit 90ad4d1c4e7ef9ccd8e6b30ee9b771dd6187f372 diff --git a/python/damask/_result.py b/python/damask/_result.py index 941eacff2..f370d24f0 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -29,7 +29,7 @@ h5py3 = h5py.__version__[0] == '3' def _read(dataset): """Read a dataset and its metadata into a numpy.ndarray.""" - metadata = {k:(v if h5py3 else v.decode()) for k,v in dataset.attrs.items()} + metadata = {k:(v.decode() if not h5py3 and type(v) is bytes else v) for k,v in dataset.attrs.items()} dtype = np.dtype(dataset.dtype,metadata=metadata) return np.array(dataset,dtype=dtype) @@ -268,9 +268,9 @@ class Result: Parameters ---------- - what : str - Attribute to change (must be from self.visible). - datasets : list of str or bool + what : {'increments', 'times', 'phases', 'homogenizations', 'fields'} + Attribute to change. + datasets : int (for increments), float (for times), str or list of, bool Name of datasets as list; supports ? and * wildcards. True is equivalent to *, False is equivalent to []. @@ -284,9 +284,9 @@ class Result: Parameters ---------- - what : str - Attribute to change (must be from self.visible). - datasets : list of str or bool + what : {'increments', 'times', 'phases', 'homogenizations', 'fields'} + Attribute to change. + datasets : int (for increments), float (for times), str or list of, bool Name of datasets as list; supports ? and * wildcards. True is equivalent to *, False is equivalent to []. @@ -300,9 +300,9 @@ class Result: Parameters ---------- - what : str - Attribute to change (must be from self.visible). - datasets : list of str or bool + what : {'increments', 'times', 'phases', 'homogenizations', 'fields'} + Attribute to change. + datasets : int (for increments), float (for times), str or list of, bool Name of datasets as list; supports ? and * wildcards. True is equivalent to *, False is equivalent to []. @@ -1016,11 +1016,14 @@ class Result: """ Write XDMF file to directly visualize data in DADF5 file. - The view is not taken into account, i.e. the content of the - whole file will be included. + Parameters + ---------- + output : str or list of str + Labels of the datasets to read. Defaults to '*', in which + case all datasets are considered. + """ - # compatibility hack - u = 'Unit' if self.version_minor < 12 else 'unit' + u = 'Unit' if self.version_minor < 12 else 'unit' # compatibility hack if self.N_constituents != 1 or len(self.phases) != 1 or not self.structured: raise TypeError('XDMF output requires homogeneous grid') @@ -1047,10 +1050,11 @@ class Result: time.attrib={'TimeType': 'List'} time_data = ET.SubElement(time, 'DataItem') + times = [self.times[self.increments.index(i)] for i in self.visible['increments']] time_data.attrib={'Format': 'XML', 'NumberType': 'Float', - 'Dimensions': f'{len(self.times)}'} - time_data.text = ' '.join(map(str,self.times)) + 'Dimensions': f'{len(times)}'} + time_data.text = ' '.join(map(str,times)) attributes = [] data_items = [] @@ -1100,7 +1104,6 @@ class Result: shape = f[name].shape[1:] dtype = f[name].dtype - if dtype not in np.sctypes['int']+np.sctypes['uint']+np.sctypes['float']: continue unit = f[name].attrs[u] if h5py3 else f[name].attrs[u].decode() attributes.append(ET.SubElement(grid, 'Attribute')) @@ -1119,7 +1122,7 @@ class Result: f.write(xml.dom.minidom.parseString(ET.tostring(xdmf).decode()).toprettyxml()) - def save_VTK(self,output='*',mode='cell',constituents=None,fill_float=np.nan,fill_int=0): + def save_VTK(self,output='*',mode='cell',constituents=None,fill_float=np.nan,fill_int=0,parallel=True): """ Export to vtk cell/point data. @@ -1140,6 +1143,9 @@ class Result: fill_int : int Fill value for non-existent entries of integer type. Defaults to 0. + parallel : bool + Write out VTK files in parallel in a separate background process. + Defaults to True. """ if mode.lower()=='cell': @@ -1147,7 +1153,7 @@ class Result: elif mode.lower()=='point': v = VTK.from_poly_data(self.coordinates0_point) - ln = 3 if self.version_minor < 12 else 10 # compatibility hack + ln = 3 if self.version_minor < 12 else 10 # compatibility hack N_digits = int(np.floor(np.log10(max(1,int(self.increments[-1][ln:])))))+1 constituents_ = constituents if isinstance(constituents,Iterable) else \ @@ -1156,9 +1162,9 @@ class Result: suffixes = [''] if self.N_constituents == 1 or isinstance(constituents,int) else \ [f'#{c}' for c in constituents_] - grp = 'mapping' if self.version_minor < 12 else 'cell_to' # compatibility hack - name = 'Name' if self.version_minor < 12 else 'label' # compatibility hack - member = 'member' if self.version_minor < 12 else 'entry' # compatibility hack + grp = 'mapping' if self.version_minor < 12 else 'cell_to' # compatibility hack + name = 'Name' if self.version_minor < 12 else 'label' # compatibility hack + member = 'member' if self.version_minor < 12 else 'entry' # compatibility hack with h5py.File(self.fname,'r') as f: @@ -1207,7 +1213,7 @@ class Result: for label,dataset in outs.items(): v.add(dataset,' / '.join(['/'.join([ty,field,label]),dataset.dtype.metadata['unit']])) - v.save(f'{self.fname.stem}_inc{inc[ln:].zfill(N_digits)}') + v.save(f'{self.fname.stem}_inc{inc[ln:].zfill(N_digits)}',parallel=parallel) def read(self,output='*',flatten=True,prune=True): @@ -1294,9 +1300,9 @@ class Result: suffixes = [''] if self.N_constituents == 1 or isinstance(constituents,int) else \ [f'#{c}' for c in constituents_] - grp = 'mapping' if self.version_minor < 12 else 'cell_to' # compatibility hack - name = 'Name' if self.version_minor < 12 else 'label' # compatibility hack - member = 'member' if self.version_minor < 12 else 'entry' # compatibility hack + grp = 'mapping' if self.version_minor < 12 else 'cell_to' # compatibility hack + name = 'Name' if self.version_minor < 12 else 'label' # compatibility hack + member = 'member' if self.version_minor < 12 else 'entry' # compatibility hack with h5py.File(self.fname,'r') as f: diff --git a/python/damask/_table.py b/python/damask/_table.py index e5f436f75..01d8c9863 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -230,7 +230,6 @@ class Table: f = fname f.seek(0) - f.seek(0) comments = [] line = f.readline().strip() while line.startswith('#'): @@ -515,7 +514,7 @@ class Table: """ if set(self.shapes) & set(other.shapes) or self.data.shape[0] != other.data.shape[0]: - raise KeyError('Dublicated keys or row count mismatch') + raise KeyError('Duplicated keys or row count mismatch') else: dup = self.copy() dup.data = dup.data.join(other.data) diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 8365e69e3..766046369 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -9,7 +9,6 @@ from datetime import datetime import pytest import numpy as np -import h5py from damask import Result from damask import Rotation From c3a7a85f7a3945ac9764a8775bff594bcc7366fb Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 5 Apr 2021 15:41:28 +0200 Subject: [PATCH 116/219] avoid repetition --- python/damask/_result.py | 59 ++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index f370d24f0..e973bfea6 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -674,7 +674,7 @@ class Result: elif T_sym['meta']['unit'] == 'Pa': k = 'stress' if k not in ['stress', 'strain']: - raise ValueError('invalid von Mises kind {kind}') + raise ValueError(f'invalid von Mises kind {kind}') return { 'data': (mechanics.equivalent_strain_Mises if k=='strain' else \ @@ -1122,6 +1122,29 @@ class Result: f.write(xml.dom.minidom.parseString(ET.tostring(xdmf).decode()).toprettyxml()) + def _mappings(self): + grp = 'mapping' if self.version_minor < 12 else 'cell_to' # compatibility hack + name = 'Name' if self.version_minor < 12 else 'label' # compatibility hack + member = 'member' if self.version_minor < 12 else 'entry' # compatibility hack + + with h5py.File(self.fname,'r') as f: + + at_cell_ph = [] + in_data_ph = [] + for c in range(self.N_constituents): + at_cell_ph.append({label: np.where(f['/'.join([grp,'phase'])][:,c][name] == label.encode())[0] \ + for label in self.visible['phases']}) + in_data_ph.append({label: f['/'.join([grp,'phase'])][member][at_cell_ph[c][label]][:,c] \ + for label in self.visible['phases']}) + + at_cell_ho = {label: np.where(f['/'.join([grp,'homogenization'])][:][name] == label.encode())[0] \ + for label in self.visible['homogenizations']} + in_data_ho = {label: f['/'.join([grp,'homogenization'])][member][at_cell_ho[label]] \ + for label in self.visible['homogenizations']} + + return at_cell_ph,in_data_ph,at_cell_ho,in_data_ho + + def save_VTK(self,output='*',mode='cell',constituents=None,fill_float=np.nan,fill_int=0,parallel=True): """ Export to vtk cell/point data. @@ -1162,25 +1185,10 @@ class Result: suffixes = [''] if self.N_constituents == 1 or isinstance(constituents,int) else \ [f'#{c}' for c in constituents_] - grp = 'mapping' if self.version_minor < 12 else 'cell_to' # compatibility hack - name = 'Name' if self.version_minor < 12 else 'label' # compatibility hack - member = 'member' if self.version_minor < 12 else 'entry' # compatibility hack + at_cell_ph,in_data_ph,at_cell_ho,in_data_ho = self._mappings() with h5py.File(self.fname,'r') as f: - at_cell_ph = [] - in_data_ph = [] - for c in range(self.N_constituents): - at_cell_ph.append({label: np.where(f['/'.join([grp,'phase'])][:,c][name] == label.encode())[0] \ - for label in self.visible['phases']}) - in_data_ph.append({label: f['/'.join([grp,'phase'])][member][at_cell_ph[c][label]][:,c] \ - for label in self.visible['phases']}) - - at_cell_ho = {label: np.where(f['/'.join([grp,'homogenization'])][:][name] == label.encode())[0] \ - for label in self.visible['homogenizations']} - in_data_ho = {label: f['/'.join([grp,'homogenization'])][member][at_cell_ho[label]] \ - for label in self.visible['homogenizations']} - for inc in util.show_progress(self.visible['increments']): u = _read(f['/'.join([inc,'geometry','u_n' if mode.lower() == 'cell' else 'u_p'])]) @@ -1300,25 +1308,10 @@ class Result: suffixes = [''] if self.N_constituents == 1 or isinstance(constituents,int) else \ [f'#{c}' for c in constituents_] - grp = 'mapping' if self.version_minor < 12 else 'cell_to' # compatibility hack - name = 'Name' if self.version_minor < 12 else 'label' # compatibility hack - member = 'member' if self.version_minor < 12 else 'entry' # compatibility hack + at_cell_ph,in_data_ph,at_cell_ho,in_data_ho = self._mappings() with h5py.File(self.fname,'r') as f: - at_cell_ph = [] - in_data_ph = [] - for c in range(self.N_constituents): - at_cell_ph.append({label: np.where(f['/'.join([grp,'phase'])][:,c][name] == label.encode())[0] \ - for label in self.visible['phases']}) - in_data_ph.append({label: f['/'.join([grp,'phase'])][member][at_cell_ph[c][label]][:,c] \ - for label in self.visible['phases']}) - - at_cell_ho = {label: np.where(f['/'.join([grp,'homogenization'])][:][name] == label.encode())[0] \ - for label in self.visible['homogenizations']} - in_data_ho = {label: f['/'.join([grp,'homogenization'])][member][at_cell_ho[label]] \ - for label in self.visible['homogenizations']} - for inc in util.show_progress(self.visible['increments']): r[inc] = {'phase':{},'homogenization':{},'geometry':{}} From faa9e6aa6a4e1476248868ba7ca1bfab6b04600b Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 5 Apr 2021 15:58:10 +0200 Subject: [PATCH 117/219] open file only once --- python/damask/_result.py | 41 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index e973bfea6..07b66f139 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1059,33 +1059,32 @@ class Result: attributes = [] data_items = [] - for inc in self.visible['increments']: + with h5py.File(self.fname,'r') as f: + for inc in self.visible['increments']: - grid=ET.SubElement(collection,'Grid') - grid.attrib = {'GridType': 'Uniform', - 'Name': inc} + grid=ET.SubElement(collection,'Grid') + grid.attrib = {'GridType': 'Uniform', + 'Name': inc} - topology=ET.SubElement(grid, 'Topology') - topology.attrib={'TopologyType': '3DCoRectMesh', - 'Dimensions': '{} {} {}'.format(*self.cells+1)} + topology=ET.SubElement(grid, 'Topology') + topology.attrib={'TopologyType': '3DCoRectMesh', + 'Dimensions': '{} {} {}'.format(*self.cells+1)} - geometry=ET.SubElement(grid, 'Geometry') - geometry.attrib={'GeometryType':'Origin_DxDyDz'} + geometry=ET.SubElement(grid, 'Geometry') + geometry.attrib={'GeometryType':'Origin_DxDyDz'} - origin=ET.SubElement(geometry, 'DataItem') - origin.attrib={'Format': 'XML', - 'NumberType': 'Float', - 'Dimensions': '3'} - origin.text="{} {} {}".format(*self.origin) + origin=ET.SubElement(geometry, 'DataItem') + origin.attrib={'Format': 'XML', + 'NumberType': 'Float', + 'Dimensions': '3'} + origin.text="{} {} {}".format(*self.origin) - delta=ET.SubElement(geometry, 'DataItem') - delta.attrib={'Format': 'XML', - 'NumberType': 'Float', - 'Dimensions': '3'} - delta.text="{} {} {}".format(*(self.size/self.cells)) + delta=ET.SubElement(geometry, 'DataItem') + delta.attrib={'Format': 'XML', + 'NumberType': 'Float', + 'Dimensions': '3'} + delta.text="{} {} {}".format(*(self.size/self.cells)) - - with h5py.File(self.fname,'r') as f: attributes.append(ET.SubElement(grid, 'Attribute')) attributes[-1].attrib={'Name': 'u / m', 'Center': 'Node', From 115e3dd4c73043b2c01c65a0797e8d4af09f9234 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 5 Apr 2021 16:32:28 +0200 Subject: [PATCH 118/219] simplified --- python/damask/_grid.py | 28 +++++++++++++++++----------- python/damask/_result.py | 2 +- python/damask/util.py | 24 ++---------------------- python/tests/test_Grid.py | 7 +++---- 4 files changed, 23 insertions(+), 38 deletions(-) diff --git a/python/damask/_grid.py b/python/damask/_grid.py index 200541cf5..5457643ee 100644 --- a/python/damask/_grid.py +++ b/python/damask/_grid.py @@ -81,26 +81,32 @@ class Grid: """ message = [] if np.any(other.cells != self.cells): - message.append(util.deemph(f'cells a b c: {util.srepr(other.cells," x ")}')) - message.append(util.emph( f'cells a b c: {util.srepr( self.cells," x ")}')) + message.append(util.deemph(f'cells x y z: {util.srepr(other.cells," x ")}')) + message.append(util.emph( f'cells x y z: {util.srepr( self.cells," x ")}')) if not np.allclose(other.size,self.size): - message.append(util.deemph(f'size x y z: {util.srepr(other.size," x ")}')) - message.append(util.emph( f'size x y z: {util.srepr( self.size," x ")}')) + message.append(util.deemph(f'size x y z: {util.srepr(other.size," x ")}')) + message.append(util.emph( f'size x y z: {util.srepr( self.size," x ")}')) if not np.allclose(other.origin,self.origin): - message.append(util.deemph(f'origin x y z: {util.srepr(other.origin," ")}')) - message.append(util.emph( f'origin x y z: {util.srepr( self.origin," ")}')) + message.append(util.deemph(f'origin x y z: {util.srepr(other.origin," ")}')) + message.append(util.emph( f'origin x y z: {util.srepr( self.origin," ")}')) if other.N_materials != self.N_materials: - message.append(util.deemph(f'# materials: {other.N_materials}')) - message.append(util.emph( f'# materials: { self.N_materials}')) + message.append(util.deemph(f'# materials: {other.N_materials}')) + message.append(util.emph( f'# materials: { self.N_materials}')) + + if np.nanmin(other.material) != np.nanmin(self.material): + message.append(util.deemph(f'min material: {np.nanmin(other.material)}')) + message.append(util.emph( f'min material: {np.nanmin( self.material)}')) if np.nanmax(other.material) != np.nanmax(self.material): - message.append(util.deemph(f'max material: {np.nanmax(other.material)}')) - message.append(util.emph( f'max material: {np.nanmax( self.material)}')) + message.append(util.deemph(f'max material: {np.nanmax(other.material)}')) + message.append(util.emph( f'max material: {np.nanmax( self.material)}')) - return util.return_message(message) + print(util.srepr(message)) + + return True if message != [] or (other.material != self.material).any() else False @property diff --git a/python/damask/_result.py b/python/damask/_result.py index 07b66f139..7cfe66c0b 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1234,7 +1234,7 @@ class Result: ---------- output : str or list of str Labels of the datasets to read. Defaults to '*', in which - case all datasets are placed. + case all datasets are read. flatten : bool Remove singular levels of the folder hierarchy. This might be beneficial in case of single increment, diff --git a/python/damask/util.py b/python/damask/util.py index 904277852..3fe30320a 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -22,7 +22,6 @@ __all__=[ 'scale_to_coprime', 'project_stereographic', 'hybrid_IA', - 'return_message', 'execution_stamp', 'shapeshifter', 'shapeblender', 'extend_docstring', 'extended_docstring', @@ -64,7 +63,8 @@ def srepr(arg,glue = '\n'): (hasattr(arg, '__getitem__') or hasattr(arg, '__iter__'))): return glue.join(str(x) for x in arg) - return arg if isinstance(arg,str) else repr(arg) + else: + return arg if isinstance(arg,str) else repr(arg) def emph(what): @@ -463,26 +463,6 @@ def dict_flatten(d): #################################################################################################### # Classes #################################################################################################### -class return_message: - """Object with formatted return message.""" - - def __init__(self,message): - """ - Set return message. - - Parameters - ---------- - message : str or list of str - message for output to screen - - """ - self.message = message - - def __repr__(self): - """Return message suitable for interactive shells.""" - return srepr(self.message) - - class _ProgressBar: """ Report progress of an interation as a status bar. diff --git a/python/tests/test_Grid.py b/python/tests/test_Grid.py index 24d48bd56..6ccd100fc 100644 --- a/python/tests/test_Grid.py +++ b/python/tests/test_Grid.py @@ -14,8 +14,7 @@ from damask import grid_filters def grid_equal(a,b): return np.all(a.material == b.material) and \ np.all(a.cells == b.cells) and \ - np.allclose(a.size, b.size) and \ - str(a.diff(b)) == str(b.diff(a)) + np.allclose(a.size, b.size) @pytest.fixture def default(): @@ -43,12 +42,12 @@ class TestGrid: print('patched datetime.datetime.now') def test_diff_equal(self,default): - assert str(default.diff(default)) == '' + assert not default.diff(default) def test_diff_not_equal(self,default): new = Grid(default.material[1:,1:,1:]+1,default.size*.9,np.ones(3)-default.origin,comments=['modified']) - assert str(default.diff(new)) != '' + assert default.diff(new) def test_repr(self,default): print(default) From d5806075d4ec18b819206c4d279a65fa4d858152 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 5 Apr 2021 18:24:03 +0200 Subject: [PATCH 119/219] distinguish isclose/allclose and __eq__ --- python/damask/_orientation.py | 57 ++++++++++++++++++++++++- python/damask/_rotation.py | 66 +++++++++++++++++++++++------ python/tests/test_ConfigMaterial.py | 3 +- python/tests/test_Orientation.py | 2 +- python/tests/test_Rotation.py | 4 +- 5 files changed, 114 insertions(+), 18 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index bbb682e82..0a48279af 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -239,7 +239,9 @@ class Orientation(Rotation): """ matching_type = all([hasattr(other,attr) and getattr(self,attr) == getattr(other,attr) for attr in ['family','lattice','parameters']]) - return np.logical_and(super().__eq__(other),matching_type) + s = self if self.family is None else self.reduced + o = other if other.family is None else other.reduced + return np.logical_and(super(__class__,s).__eq__(o),matching_type) def __ne__(self,other): """ @@ -254,6 +256,59 @@ class Orientation(Rotation): return np.logical_not(self==other) + def isclose(self,other,rtol=1e-5,atol=1e-8,equal_nan=True): + """ + Report where values are approximately equal to corresponding ones of other Orientation. + + Parameters + ---------- + other : Orientation + Orientation to compare against. + rtol : float, optional + Relative tolerance of equality. + atol : float, optional + Absolute tolerance of equality. + equal_nan : bool, optional + Consider matching NaN values as equal. Defaults to True. + + Returns + ------- + mask : numpy.ndarray bool + Mask indicating where corresponding orientations are close. + + """ + matching_type = all([hasattr(other,attr) and getattr(self,attr) == getattr(other,attr) + for attr in ['family','lattice','parameters']]) + s = self if self.family is None else self.reduced + o = other if other.family is None else other.reduced + return np.logical_and(super(__class__,s).isclose(o),matching_type) + + + + def allclose(self,other,rtol=1e-5,atol=1e-8,equal_nan=True): + """ + Test whether all values are approximately equal to corresponding ones of other Orientation. + + Parameters + ---------- + other : Orientation + Orientation to compare against. + rtol : float, optional + Relative tolerance of equality. + atol : float, optional + Absolute tolerance of equality. + equal_nan : bool, optional + Consider matching NaN values as equal. Defaults to True. + + Returns + ------- + answer : bool + Whether all values are close between both orientations. + + """ + return np.all(self.isclose(other,rtol,atol,equal_nan)) + + def __mul__(self,other): """ Compose this orientation with other. diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index a067209b2..fff53fc73 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -103,29 +103,20 @@ class Rotation: """ Equal to other. - Equality is determined taking limited floating point precision into account. - See numpy.allclose for details. - Parameters ---------- other : Rotation Rotation to check for equality. """ - s = self.quaternion - o = other.quaternion - if self.shape == () == other.shape: - return np.allclose(s,o) or (np.isclose(s[0],0.0) and np.allclose(s,-1.0*o)) - else: - return np.all(np.isclose(s,o),-1) + np.all(np.isclose(s,-1.0*o),-1) * np.isclose(s[...,0],0.0) + return np.logical_or(np.all(self.quaternion == other.quaternion,axis=-1), + np.all(self.quaternion == -1.0*other.quaternion,axis=-1)) + def __ne__(self,other): """ Not equal to other. - Equality is determined taking limited floating point precision into - account. See numpy.allclose for details. - Parameters ---------- other : Rotation @@ -135,6 +126,57 @@ class Rotation: return np.logical_not(self==other) + def isclose(self,other,rtol=1e-5,atol=1e-8,equal_nan=True): + """ + Report where values are approximately equal to corresponding ones of other Rotation. + + Parameters + ---------- + other : Rotation + Rotation to compare against. + rtol : float, optional + Relative tolerance of equality. + atol : float, optional + Absolute tolerance of equality. + equal_nan : bool, optional + Consider matching NaN values as equal. Defaults to True. + + Returns + ------- + mask : numpy.ndarray bool + Mask indicating where corresponding rotations are close. + + """ + s = self.quaternion + o = other.quaternion + return np.logical_or(np.all(np.isclose(s, o,rtol,atol,equal_nan),axis=-1), + np.all(np.isclose(s,-1.0*o,rtol,atol,equal_nan),axis=-1)) + + + def allclose(self,other,rtol=1e-5,atol=1e-8,equal_nan=True): + """ + Test whether all values are approximately equal to corresponding ones of other Rotation. + + Parameters + ---------- + other : Rotation + Rotation to compare against. + rtol : float, optional + Relative tolerance of equality. + atol : float, optional + Absolute tolerance of equality. + equal_nan : bool, optional + Consider matching NaN values as equal. Defaults to True. + + Returns + ------- + answer : bool + Whether all values are close between both rotations. + + """ + return np.all(self.isclose(other,rtol,atol,equal_nan)) + + def __array__(self): """Initializer for numpy.""" return self.quaternion diff --git a/python/tests/test_ConfigMaterial.py b/python/tests/test_ConfigMaterial.py index cf4a8ab9d..98a557ae8 100644 --- a/python/tests/test_ConfigMaterial.py +++ b/python/tests/test_ConfigMaterial.py @@ -140,6 +140,5 @@ class TestConfigMaterial: if update: cur.save(ref_path/'measured.material_yaml') for i,m in enumerate(ref['material']): - assert Rotation(m['constituents'][0]['O']) == \ - Rotation(cur['material'][i]['constituents'][0]['O']) + assert Rotation(m['constituents'][0]['O']).isclose(Rotation(cur['material'][i]['constituents'][0]['O'])) assert cur.is_valid and cur['phase'] == ref['phase'] and cur['homogenization'] == ref['homogenization'] diff --git a/python/tests/test_Orientation.py b/python/tests/test_Orientation.py index 40d4d0116..6f3503b73 100644 --- a/python/tests/test_Orientation.py +++ b/python/tests/test_Orientation.py @@ -222,7 +222,7 @@ class TestOrientation: blend = util.shapeblender(o.shape,p.shape) for loc in np.random.randint(0,blend,(10,len(blend))): assert o[tuple(loc[:len(o.shape)])].disorientation(p[tuple(loc[-len(p.shape):])]) \ - == o.disorientation(p)[tuple(loc)] + .isclose(o.disorientation(p)[tuple(loc)]) @pytest.mark.parametrize('lattice',Orientation.crystal_families) def test_disorientation360(self,lattice): diff --git a/python/tests/test_Rotation.py b/python/tests/test_Rotation.py index b28a849c5..9d0f26bfc 100644 --- a/python/tests/test_Rotation.py +++ b/python/tests/test_Rotation.py @@ -960,7 +960,7 @@ class TestRotation: if axis_angle[3] > np.pi: axis_angle[3] -= 2.*np.pi axis_angle *= -1 - assert R**pwr == Rotation.from_axis_angle(axis_angle) + assert (R**pwr).isclose(Rotation.from_axis_angle(axis_angle)) def test_rotate_inverse(self): R = Rotation.from_random() @@ -1027,7 +1027,7 @@ class TestRotation: def test_invariant(self): R = Rotation.from_random() - assert R/R == R*R**(-1) == Rotation() + assert (R/R).isclose(R*R**(-1)) and (R/R).isclose(Rotation()) @pytest.mark.parametrize('item',[np.ones(3),np.ones((3,3)), np.ones((3,3,3,3))]) def test_apply(self,item): From 02277fb820731e4ca2fcb61026a37c9ba61d8ae0 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 5 Apr 2021 22:18:18 +0200 Subject: [PATCH 120/219] consistently return masked array --- python/damask/_result.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 7cfe66c0b..dcb192cf9 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1315,7 +1315,7 @@ class Result: r[inc] = {'phase':{},'homogenization':{},'geometry':{}} for out in _match(output,f['/'.join([inc,'geometry'])].keys()): - r[inc]['geometry'][out] = _read(f['/'.join([inc,'geometry',out])]) + r[inc]['geometry'][out] = ma.array(_read(f['/'.join([inc,'geometry',out])]),fill_value = fill_float) for ty in ['phase','homogenization']: for label in self.visible[ty+'s']: From b797d9d76bbdb2d23b40a92b228105081c966659 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 6 Apr 2021 10:14:52 +0200 Subject: [PATCH 121/219] not needed --- src/phase.f90 | 58 ++++++++-------------------------------- src/phase_mechanical.f90 | 20 -------------- 2 files changed, 11 insertions(+), 67 deletions(-) diff --git a/src/phase.f90 b/src/phase.f90 index 9470ab8af..d872d8115 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -100,11 +100,6 @@ module phase integer, intent(in) :: ph end subroutine damage_results - module subroutine mechanical_windForward(ph,me) - integer, intent(in) :: ph, me - end subroutine mechanical_windForward - - module subroutine mechanical_forward() end subroutine mechanical_forward @@ -325,13 +320,12 @@ module phase phase_damage_get_phi, & phase_mechanical_getP, & phase_mechanical_setF, & - phase_mechanical_getF, & - phase_windForward + phase_mechanical_getF contains !-------------------------------------------------------------------------------------------------- -!> @brief Initialze constitutive models for individual physics +!> @brief Initialize constitutive models for individual physics !-------------------------------------------------------------------------------------------------- subroutine phase_init @@ -382,12 +376,12 @@ end subroutine phase_init !> @brief Allocate the components of the state structure for a given phase !-------------------------------------------------------------------------------------------------- subroutine phase_allocateState(state, & - Nconstituents,sizeState,sizeDotState,sizeDeltaState) + NEntries,sizeState,sizeDotState,sizeDeltaState) class(tState), intent(out) :: & state integer, intent(in) :: & - Nconstituents, & + NEntries, & sizeState, & sizeDotState, & sizeDeltaState @@ -398,13 +392,13 @@ subroutine phase_allocateState(state, & state%sizeDeltaState = sizeDeltaState state%offsetDeltaState = sizeState-sizeDeltaState ! deltaState occupies latter part of state by definition - allocate(state%atol (sizeState), source=0.0_pReal) - allocate(state%state0 (sizeState,Nconstituents), source=0.0_pReal) - allocate(state%state (sizeState,Nconstituents), source=0.0_pReal) + allocate(state%atol (sizeState), source=0.0_pReal) + allocate(state%state0 (sizeState,NEntries), source=0.0_pReal) + allocate(state%state (sizeState,NEntries), source=0.0_pReal) - allocate(state%dotState (sizeDotState,Nconstituents), source=0.0_pReal) + allocate(state%dotState (sizeDotState,NEntries), source=0.0_pReal) - allocate(state%deltaState (sizeDeltaState,Nconstituents), source=0.0_pReal) + allocate(state%deltaState (sizeDeltaState,NEntries), source=0.0_pReal) end subroutine phase_allocateState @@ -567,34 +561,6 @@ subroutine crystallite_init() end subroutine crystallite_init -!-------------------------------------------------------------------------------------------------- -!> @brief Wind homog inc forward. -!-------------------------------------------------------------------------------------------------- -subroutine phase_windForward(ip,el) - - integer, intent(in) :: & - ip, & !< integration point number - el !< element number - - integer :: & - co, & !< constituent number - so, ph, me - - - do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) - ph = material_phaseAt(co,el) - me = material_phaseMemberAt(co,ip,el) - - call mechanical_windForward(ph,me) - - if(damageState(ph)%sizeState > 0) damageState(ph)%state0(:,me) = damageState(ph)%state(:,me) - - - enddo - -end subroutine phase_windForward - - !-------------------------------------------------------------------------------------------------- !> @brief calculates orientations !-------------------------------------------------------------------------------------------------- @@ -658,8 +624,7 @@ end function converged !-------------------------------------------------------------------------------------------------- -!> @brief Write current restart information (Field and constitutive data) to file. -! ToDo: Merge data into one file for MPI +!> @brief Write restart data to file. !-------------------------------------------------------------------------------------------------- subroutine phase_restartWrite(fileHandle) @@ -687,8 +652,7 @@ end subroutine phase_restartWrite !-------------------------------------------------------------------------------------------------- -!> @brief Read data for restart -! ToDo: Merge data into one file for MPI +!> @brief Read restart data from file. !-------------------------------------------------------------------------------------------------- subroutine phase_restartRead(fileHandle) diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index c507ce20c..e8cf406ef 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -1060,26 +1060,6 @@ subroutine crystallite_results(group,ph) end subroutine crystallite_results -!-------------------------------------------------------------------------------------------------- -!> @brief Wind homog inc forward. -!-------------------------------------------------------------------------------------------------- -module subroutine mechanical_windForward(ph,me) - - integer, intent(in) :: ph, me - - - phase_mechanical_Fp0(ph)%data(1:3,1:3,me) = phase_mechanical_Fp(ph)%data(1:3,1:3,me) - phase_mechanical_Fi0(ph)%data(1:3,1:3,me) = phase_mechanical_Fi(ph)%data(1:3,1:3,me) - phase_mechanical_F0(ph)%data(1:3,1:3,me) = phase_mechanical_F(ph)%data(1:3,1:3,me) - phase_mechanical_Li0(ph)%data(1:3,1:3,me) = phase_mechanical_Li(ph)%data(1:3,1:3,me) - phase_mechanical_Lp0(ph)%data(1:3,1:3,me) = phase_mechanical_Lp(ph)%data(1:3,1:3,me) - phase_mechanical_S0(ph)%data(1:3,1:3,me) = phase_mechanical_S(ph)%data(1:3,1:3,me) - - plasticState(ph)%State0(:,me) = plasticState(ph)%state(:,me) - -end subroutine mechanical_windForward - - !-------------------------------------------------------------------------------------------------- !> @brief Forward data after successful increment. ! ToDo: Any guessing for the current states possible? From 2b798589ce36e0d3203021b523d9e9ea8171772d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 6 Apr 2021 10:22:47 +0200 Subject: [PATCH 122/219] modularizing --- src/phase.f90 | 13 ++++--------- src/phase_damage.f90 | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/phase.f90 b/src/phase.f90 index d872d8115..cb5845318 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -103,6 +103,9 @@ module phase module subroutine mechanical_forward() end subroutine mechanical_forward + module subroutine damage_forward() + end subroutine damage_forward + module subroutine thermal_forward() end subroutine thermal_forward @@ -429,21 +432,13 @@ end subroutine phase_restore !-------------------------------------------------------------------------------------------------- !> @brief Forward data after successful increment. -! ToDo: Any guessing for the current states possible? !-------------------------------------------------------------------------------------------------- subroutine phase_forward() - integer :: ph - - call mechanical_forward() + call damage_forward() call thermal_forward() - do ph = 1, size(damageState) - if (damageState(ph)%sizeState > 0) & - damageState(ph)%state0 = damageState(ph)%state - enddo - end subroutine phase_forward diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index c6b430b74..9659e5fea 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -503,4 +503,21 @@ module function damage_phi(ph,me) result(phi) end function damage_phi + +!-------------------------------------------------------------------------------------------------- +!> @brief Forward data after successful increment. +!-------------------------------------------------------------------------------------------------- +module subroutine damage_forward() + + integer :: ph + + + do ph = 1, size(damageState) + if (damageState(ph)%sizeState > 0) & + damageState(ph)%state0 = damageState(ph)%state + enddo + +end subroutine damage_forward + + end submodule damagee From 869976c7a07f92732e38207332ad660d497062bc Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 6 Apr 2021 11:38:44 +0200 Subject: [PATCH 123/219] new names --- src/homogenization.f90 | 14 +-- src/homogenization_damage.f90 | 26 +++--- src/homogenization_mechanical.f90 | 30 +++--- src/homogenization_mechanical_RGC.f90 | 92 +++++++++---------- src/homogenization_thermal.f90 | 34 +++---- src/material.f90 | 24 ++--- src/phase.f90 | 21 ++--- src/phase_damage.f90 | 10 +- src/phase_damage_anisoductile.f90 | 18 ++-- src/phase_damage_isobrittle.f90 | 18 ++-- src/phase_damage_isoductile.f90 | 18 ++-- src/phase_mechanical.f90 | 16 ++-- ...phase_mechanical_plastic_dislotungsten.f90 | 2 +- src/phase_mechanical_plastic_dislotwin.f90 | 2 +- src/phase_mechanical_plastic_isotropic.f90 | 2 +- ...phase_mechanical_plastic_kinehardening.f90 | 2 +- src/phase_mechanical_plastic_none.f90 | 2 +- src/phase_mechanical_plastic_nonlocal.f90 | 8 +- ...phase_mechanical_plastic_phenopowerlaw.f90 | 2 +- src/phase_thermal.f90 | 6 +- src/phase_thermal_dissipation.f90 | 2 +- src/phase_thermal_externalheat.f90 | 2 +- 22 files changed, 174 insertions(+), 177 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 7dfaf5b37..3e4e18f56 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -259,25 +259,25 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE NiterationMPstate, & ip, & !< integration point number el, & !< element number - myNgrains, co, ce, ho, me, ph + myNgrains, co, ce, ho, en, ph logical :: & converged logical, dimension(2) :: & doneAndHappy !$OMP PARALLEL - !$OMP DO PRIVATE(ce,me,ho,myNgrains,NiterationMPstate,converged,doneAndHappy) + !$OMP DO PRIVATE(ce,en,ho,myNgrains,NiterationMPstate,converged,doneAndHappy) do el = FEsolving_execElem(1),FEsolving_execElem(2) ho = material_homogenizationAt(el) myNgrains = homogenization_Nconstituents(ho) do ip = FEsolving_execIP(1),FEsolving_execIP(2) ce = (el-1)*discretization_nIPs + ip - me = material_homogenizationMemberAt2(ce) + en = material_homogenizationEntry(ce) call phase_restore(ce,.false.) ! wrong name (is more a forward function) - if(homogState(ho)%sizeState > 0) homogState(ho)%state(:,me) = homogState(ho)%state0(:,me) - if(damageState_h(ho)%sizeState > 0) damageState_h(ho)%state(:,me) = damageState_h(ho)%state0(:,me) + if(homogState(ho)%sizeState > 0) homogState(ho)%state(:,en) = homogState(ho)%state0(:,en) + if(damageState_h(ho)%sizeState > 0) damageState_h(ho)%state(:,en) = damageState_h(ho)%state0(:,en) call damage_partition(ce) doneAndHappy = [.false.,.true.] @@ -505,12 +505,12 @@ function damage_nonlocal_getDiffusion(ce) ho, & co - ho = material_homogenizationAt2(ce) + ho = material_homogenizationID(ce) damage_nonlocal_getDiffusion = 0.0_pReal do co = 1, homogenization_Nconstituents(ho) damage_nonlocal_getDiffusion = damage_nonlocal_getDiffusion + & - crystallite_push33ToRef(co,ce,lattice_D(1:3,1:3,material_phaseAt2(co,ce))) + crystallite_push33ToRef(co,ce,lattice_D(1:3,1:3,material_phaseID(co,ce))) enddo damage_nonlocal_getDiffusion = & diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index 495cb0beb..203c45670 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -42,7 +42,7 @@ module subroutine damage_init() allocate(current(configHomogenizations%length)) do ho = 1, configHomogenizations%length - allocate(current(ho)%phi(count(material_homogenizationAt2==ho)), source=1.0_pReal) + allocate(current(ho)%phi(count(material_homogenizationID==ho)), source=1.0_pReal) configHomogenization => configHomogenizations%get(ho) associate(prm => param(ho)) if (configHomogenization%contains('damage')) then @@ -72,9 +72,9 @@ module subroutine damage_partition(ce) integer :: co - if(damageState_h(material_homogenizationAt2(ce))%sizeState < 1) return - phi = damagestate_h(material_homogenizationAt2(ce))%state(1,material_homogenizationMemberAt2(ce)) - do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce)) + if(damageState_h(material_homogenizationID(ce))%sizeState < 1) return + phi = damagestate_h(material_homogenizationID(ce))%state(1,material_homogenizationEntry(ce)) + do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) call phase_damage_set_phi(phi,co,ce) enddo @@ -94,11 +94,11 @@ module function damage_nonlocal_getMobility(ce) result(M) M = 0.0_pReal - do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce)) - M = M + lattice_M(material_phaseAt2(co,ce)) + do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) + M = M + lattice_M(material_phaseID(co,ce)) enddo - M = M/real(homogenization_Nconstituents(material_homogenizationAt2(ce)),pReal) + M = M/real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) end function damage_nonlocal_getMobility @@ -118,8 +118,8 @@ module subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, p dPhiDot_dPhi = 0.0_pReal call phase_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ce) - phiDot = phiDot/real(homogenization_Nconstituents(material_homogenizationAt2(ce)),pReal) - dPhiDot_dPhi = dPhiDot_dPhi/real(homogenization_Nconstituents(material_homogenizationAt2(ce)),pReal) + phiDot = phiDot/real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) + dPhiDot_dPhi = dPhiDot_dPhi/real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) end subroutine damage_nonlocal_getSourceAndItsTangent @@ -134,11 +134,11 @@ module subroutine damage_nonlocal_putNonLocalDamage(phi,ce) phi integer :: & ho, & - me + en - ho = material_homogenizationAt2(ce) - me = material_homogenizationMemberAt2(ce) - damagestate_h(ho)%state(1,me) = phi + ho = material_homogenizationID(ce) + en = material_homogenizationEntry(ce) + damagestate_h(ho)%state(1,en) = phi end subroutine damage_nonlocal_putNonLocalDamage diff --git a/src/homogenization_mechanical.f90 b/src/homogenization_mechanical.f90 index f7074bc40..35ec37f34 100644 --- a/src/homogenization_mechanical.f90 +++ b/src/homogenization_mechanical.f90 @@ -110,10 +110,10 @@ module subroutine mechanical_partition(subF,ce) ce integer :: co - real(pReal), dimension (3,3,homogenization_Nconstituents(material_homogenizationAt2(ce))) :: Fs + real(pReal), dimension (3,3,homogenization_Nconstituents(material_homogenizationID(ce))) :: Fs - chosenHomogenization: select case(homogenization_type(material_homogenizationAt2(ce))) + chosenHomogenization: select case(homogenization_type(material_homogenizationID(ce))) case (HOMOGENIZATION_NONE_ID) chosenHomogenization Fs(1:3,1:3,1) = subF @@ -126,7 +126,7 @@ module subroutine mechanical_partition(subF,ce) end select chosenHomogenization - do co = 1,homogenization_Nconstituents(material_homogenizationAt2(ce)) + do co = 1,homogenization_Nconstituents(material_homogenizationID(ce)) call phase_mechanical_setF(Fs(1:3,1:3,co),co,ce) enddo @@ -143,18 +143,18 @@ module subroutine mechanical_homogenize(dt,ce) integer, intent(in) :: ce integer :: co - real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationAt2(ce))) - real(pReal) :: Ps(3,3,homogenization_Nconstituents(material_homogenizationAt2(ce))) + real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationID(ce))) + real(pReal) :: Ps(3,3,homogenization_Nconstituents(material_homogenizationID(ce))) - chosenHomogenization: select case(homogenization_type(material_homogenizationAt2(ce))) + chosenHomogenization: select case(homogenization_type(material_homogenizationID(ce))) case (HOMOGENIZATION_NONE_ID) chosenHomogenization homogenization_P(1:3,1:3,ce) = phase_mechanical_getP(1,ce) homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = phase_mechanical_dPdF(dt,1,ce) case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization - do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce)) + do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(dt,co,ce) Ps(:,:,co) = phase_mechanical_getP(co,ce) enddo @@ -162,10 +162,10 @@ module subroutine mechanical_homogenize(dt,ce) homogenization_P(1:3,1:3,ce), & homogenization_dPdF(1:3,1:3,1:3,1:3,ce),& Ps,dPdFs, & - material_homogenizationAt2(ce)) + material_homogenizationID(ce)) case (HOMOGENIZATION_RGC_ID) chosenHomogenization - do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce)) + do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(dt,co,ce) Ps(:,:,co) = phase_mechanical_getP(co,ce) enddo @@ -173,7 +173,7 @@ module subroutine mechanical_homogenize(dt,ce) homogenization_P(1:3,1:3,ce), & homogenization_dPdF(1:3,1:3,1:3,1:3,ce),& Ps,dPdFs, & - material_homogenizationAt2(ce)) + material_homogenizationID(ce)) end select chosenHomogenization @@ -195,13 +195,13 @@ module function mechanical_updateState(subdt,subF,ce) result(doneAndHappy) logical, dimension(2) :: doneAndHappy integer :: co - real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationAt2(ce))) - real(pReal) :: Fs(3,3,homogenization_Nconstituents(material_homogenizationAt2(ce))) - real(pReal) :: Ps(3,3,homogenization_Nconstituents(material_homogenizationAt2(ce))) + real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationID(ce))) + real(pReal) :: Fs(3,3,homogenization_Nconstituents(material_homogenizationID(ce))) + real(pReal) :: Ps(3,3,homogenization_Nconstituents(material_homogenizationID(ce))) - if (homogenization_type(material_homogenizationAt2(ce)) == HOMOGENIZATION_RGC_ID) then - do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce)) + if (homogenization_type(material_homogenizationID(ce)) == HOMOGENIZATION_RGC_ID) then + do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(subdt,co,ce) Fs(:,:,co) = phase_mechanical_getF(co,ce) Ps(:,:,co) = phase_mechanical_getP(co,ce) diff --git a/src/homogenization_mechanical_RGC.f90 b/src/homogenization_mechanical_RGC.f90 index 0de7a470b..366eb7a36 100644 --- a/src/homogenization_mechanical_RGC.f90 +++ b/src/homogenization_mechanical_RGC.f90 @@ -204,12 +204,12 @@ module subroutine mechanical_RGC_partitionDeformation(F,avgF,ce) real(pReal), dimension(3) :: aVect,nVect integer, dimension(4) :: intFace integer, dimension(3) :: iGrain3 - integer :: iGrain,iFace,i,j,ho,me + integer :: iGrain,iFace,i,j,ho,en - associate(prm => param(material_homogenizationAt2(ce))) + associate(prm => param(material_homogenizationID(ce))) - ho = material_homogenizationAt2(ce) - me = material_homogenizationMemberAt2(ce) + ho = material_homogenizationID(ce) + en = material_homogenizationEntry(ce) !-------------------------------------------------------------------------------------------------- ! compute the deformation gradient of individual grains due to relaxations F = 0.0_pReal @@ -217,8 +217,8 @@ module subroutine mechanical_RGC_partitionDeformation(F,avgF,ce) iGrain3 = grain1to3(iGrain,prm%N_constituents) do iFace = 1,6 intFace = getInterface(iFace,iGrain3) ! identifying 6 interfaces of each grain - aVect = relaxationVector(intFace,ho,me) ! get the relaxation vectors for each interface from global relaxation vector array - nVect = interfaceNormal(intFace,ho,me) + aVect = relaxationVector(intFace,ho,en) ! get the relaxation vectors for each interface from global relaxation vector array + nVect = interfaceNormal(intFace,ho,en) forall (i=1:3,j=1:3) & F(i,j,iGrain) = F(i,j,iGrain) + aVect(i)*nVect(j) ! calculating deformation relaxations due to interface relaxation enddo @@ -247,7 +247,7 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa integer, dimension(4) :: intFaceN,intFaceP,faceID integer, dimension(3) :: nGDim,iGr3N,iGr3P - integer :: ho,iNum,i,j,nIntFaceTot,iGrN,iGrP,iMun,iFace,k,l,ipert,iGrain,nGrain, me + integer :: ho,iNum,i,j,nIntFaceTot,iGrN,iGrP,iMun,iFace,k,l,ipert,nGrain, en real(pReal), dimension(3,3,size(P,3)) :: R,pF,pR,D,pD real(pReal), dimension(3,size(P,3)) :: NN,devNull real(pReal), dimension(3) :: normP,normN,mornP,mornN @@ -261,9 +261,9 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa return endif zeroTimeStep - ho = material_homogenizationAt2(ce) + ho = material_homogenizationID(ce) + en = material_homogenizationEntry(ce) - me = material_homogenizationMemberAt2(ce) associate(stt => state(ho), st0 => state0(ho), dst => dependentState(ho), prm => param(ho)) !-------------------------------------------------------------------------------------------------- @@ -278,16 +278,16 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa ! allocate the size of the global relaxation arrays/jacobian matrices depending on the size of the cluster allocate(resid(3*nIntFaceTot), source=0.0_pReal) allocate(tract(nIntFaceTot,3), source=0.0_pReal) - relax = stt%relaxationVector(:,me) - drelax = stt%relaxationVector(:,me) - st0%relaxationVector(:,me) + relax = stt%relaxationVector(:,en) + drelax = stt%relaxationVector(:,en) - st0%relaxationVector(:,en) !-------------------------------------------------------------------------------------------------- ! computing interface mismatch and stress penalty tensor for all interfaces of all grains - call stressPenalty(R,NN,avgF,F,ho,me) + call stressPenalty(R,NN,avgF,F,ho,en) !-------------------------------------------------------------------------------------------------- ! calculating volume discrepancy and stress penalty related to overall volume discrepancy - call volumePenalty(D,dst%volumeDiscrepancy(me),avgF,F,nGrain) + call volumePenalty(D,dst%volumeDiscrepancy(en),avgF,F,nGrain) !------------------------------------------------------------------------------------------------ ! computing the residual stress from the balance of traction at all (interior) interfaces @@ -299,7 +299,7 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa iGr3N = faceID(2:4) ! identifying the grain ID in local coordinate system (3-dimensional index) iGrN = grain3to1(iGr3N,param(ho)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index) intFaceN = getInterface(2*faceID(1),iGr3N) - normN = interfaceNormal(intFaceN,ho,me) + normN = interfaceNormal(intFaceN,ho,en) !-------------------------------------------------------------------------------------------------- ! identify the right/up/front grain (+|P) @@ -307,7 +307,7 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa iGr3P(faceID(1)) = iGr3N(faceID(1))+1 ! identifying the grain ID in local coordinate system (3-dimensional index) iGrP = grain3to1(iGr3P,param(ho)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index) intFaceP = getInterface(2*faceID(1)-1,iGr3P) - normP = interfaceNormal(intFaceP,ho,me) + normP = interfaceNormal(intFaceP,ho,en) !-------------------------------------------------------------------------------------------------- ! compute the residual of traction at the interface (in local system, 4-dimensional index) @@ -335,9 +335,9 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa if (residMax < num%rtol*stresMax .or. residMax < num%atol) then doneAndHappy = .true. - dst%mismatch(1:3,me) = sum(NN,2)/real(nGrain,pReal) - dst%relaxationRate_avg(me) = sum(abs(drelax))/dt/real(3*nIntFaceTot,pReal) - dst%relaxationRate_max(me) = maxval(abs(drelax))/dt + dst%mismatch(1:3,en) = sum(NN,2)/real(nGrain,pReal) + dst%relaxationRate_avg(en) = sum(abs(drelax))/dt/real(3*nIntFaceTot,pReal) + dst%relaxationRate_max(en) = maxval(abs(drelax))/dt return @@ -363,10 +363,10 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa iGr3N = faceID(2:4) ! identifying the grain ID in local coordinate sytem iGrN = grain3to1(iGr3N,param(ho)%N_constituents) ! translate into global grain ID intFaceN = getInterface(2*faceID(1),iGr3N) ! identifying the connecting interface in local coordinate system - normN = interfaceNormal(intFaceN,ho,me) + normN = interfaceNormal(intFaceN,ho,en) do iFace = 1,6 intFaceN = getInterface(iFace,iGr3N) ! identifying all interfaces that influence relaxation of the above interface - mornN = interfaceNormal(intFaceN,ho,me) + mornN = interfaceNormal(intFaceN,ho,en) iMun = interface4to1(intFaceN,param(ho)%N_constituents) ! translate the interfaces ID into local 4-dimensional index if (iMun > 0) then ! get the corresponding tangent do i=1,3; do j=1,3; do k=1,3; do l=1,3 @@ -384,10 +384,10 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa iGr3P(faceID(1)) = iGr3N(faceID(1))+1 ! identifying the grain ID in local coordinate sytem iGrP = grain3to1(iGr3P,param(ho)%N_constituents) ! translate into global grain ID intFaceP = getInterface(2*faceID(1)-1,iGr3P) ! identifying the connecting interface in local coordinate system - normP = interfaceNormal(intFaceP,ho,me) + normP = interfaceNormal(intFaceP,ho,en) do iFace = 1,6 intFaceP = getInterface(iFace,iGr3P) ! identifying all interfaces that influence relaxation of the above interface - mornP = interfaceNormal(intFaceP,ho,me) + mornP = interfaceNormal(intFaceP,ho,en) iMun = interface4to1(intFaceP,param(ho)%N_constituents) ! translate the interfaces ID into local 4-dimensional index if (iMun > 0) then ! get the corresponding tangent do i=1,3; do j=1,3; do k=1,3; do l=1,3 @@ -408,9 +408,9 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa do ipert = 1,3*nIntFaceTot p_relax = relax p_relax(ipert) = relax(ipert) + num%pPert ! perturb the relaxation vector - stt%relaxationVector(:,me) = p_relax - call grainDeformation(pF,avgF,ho,me) ! rain deformation from perturbed state - call stressPenalty(pR,DevNull, avgF,pF,ho,me) ! stress penalty due to interface mismatch from perturbed state + stt%relaxationVector(:,en) = p_relax + call grainDeformation(pF,avgF,ho,en) ! rain deformation from perturbed state + call stressPenalty(pR,DevNull, avgF,pF,ho,en) ! stress penalty due to interface mismatch from perturbed state call volumePenalty(pD,devNull(1,1), avgF,pF,nGrain) ! stress penalty due to volume discrepancy from perturbed state !-------------------------------------------------------------------------------------------------- @@ -424,7 +424,7 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa iGr3N = faceID(2:4) ! identify the grain ID in local coordinate system (3-dimensional index) iGrN = grain3to1(iGr3N,param(ho)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index) intFaceN = getInterface(2*faceID(1),iGr3N) ! identify the interface ID of the grain - normN = interfaceNormal(intFaceN,ho,me) + normN = interfaceNormal(intFaceN,ho,en) !-------------------------------------------------------------------------------------------------- ! identify the right/up/front grain (+|P) @@ -432,7 +432,7 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa iGr3P(faceID(1)) = iGr3N(faceID(1))+1 ! identify the grain ID in local coordinate system (3-dimensional index) iGrP = grain3to1(iGr3P,param(ho)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index) intFaceP = getInterface(2*faceID(1)-1,iGr3P) ! identify the interface ID of the grain - normP = interfaceNormal(intFaceP,ho,me) + normP = interfaceNormal(intFaceP,ho,en) !-------------------------------------------------------------------------------------------------- ! compute the residual stress (contribution of mismatch and volume penalties) from perturbed state @@ -472,7 +472,7 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa do i = 1,3*nIntFaceTot;do j = 1,3*nIntFaceTot drelax(i) = drelax(i) - jnverse(i,j)*resid(j) ! Calculate the correction for the state variable enddo; enddo - stt%relaxationVector(:,me) = relax + drelax ! Updateing the state variable for the next iteration + stt%relaxationVector(:,en) = relax + drelax ! Updateing the state variable for the next iteration if (any(abs(drelax) > num%maxdRelax)) then ! Forcing cutback when the incremental change of relaxation vector becomes too large doneAndHappy = [.true.,.false.] !$OMP CRITICAL (write2out) @@ -488,14 +488,14 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa !------------------------------------------------------------------------------------------------ !> @brief calculate stress-like penalty due to deformation mismatch !------------------------------------------------------------------------------------------------ - subroutine stressPenalty(rPen,nMis,avgF,fDef,ho,me) + subroutine stressPenalty(rPen,nMis,avgF,fDef,ho,en) real(pReal), dimension (:,:,:), intent(out) :: rPen !< stress-like penalty real(pReal), dimension (:,:), intent(out) :: nMis !< total amount of mismatch real(pReal), dimension (:,:,:), intent(in) :: fDef !< deformation gradients real(pReal), dimension (3,3), intent(in) :: avgF !< initial effective stretch tensor - integer, intent(in) :: ho, me + integer, intent(in) :: ho, en integer, dimension (4) :: intFace integer, dimension (3) :: iGrain3,iGNghb3,nGDim @@ -515,7 +515,7 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa ! get the correction factor the modulus of penalty stress representing the evolution of area of ! the interfaces due to deformations - surfCorr = surfaceCorrection(avgF,ho,me) + surfCorr = surfaceCorrection(avgF,ho,en) associate(prm => param(ho)) @@ -527,7 +527,7 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa interfaceLoop: do iFace = 1,6 intFace = getInterface(iFace,iGrain3) ! get the 4-dimensional index of the interface in local numbering system of the grain - nVect = interfaceNormal(intFace,ho,me) + nVect = interfaceNormal(intFace,ho,en) iGNghb3 = iGrain3 ! identify the neighboring grain across the interface iGNghb3(abs(intFace(1))) = iGNghb3(abs(intFace(1))) & + int(real(intFace(1),pReal)/real(abs(intFace(1)),pReal)) @@ -611,14 +611,14 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa !> @brief compute the correction factor accouted for surface evolution (area change) due to ! deformation !-------------------------------------------------------------------------------------------------- - function surfaceCorrection(avgF,ho,me) + function surfaceCorrection(avgF,ho,en) real(pReal), dimension(3) :: surfaceCorrection real(pReal), dimension(3,3), intent(in) :: avgF !< average F integer, intent(in) :: & ho, & - me + en real(pReal), dimension(3,3) :: invC real(pReal), dimension(3) :: nVect real(pReal) :: detF @@ -629,7 +629,7 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa surfaceCorrection = 0.0_pReal do iBase = 1,3 - nVect = interfaceNormal([iBase,1,1,1],ho,me) + nVect = interfaceNormal([iBase,1,1,1],ho,en) do i = 1,3; do j = 1,3 surfaceCorrection(iBase) = surfaceCorrection(iBase) + invC(i,j)*nVect(i)*nVect(j) ! compute the component of (the inverse of) the stretch in the direction of the normal enddo; enddo @@ -651,7 +651,7 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa real(pReal), dimension(6,6) :: C - C = phase_homogenizedC(material_phaseAt2(grainID,ce),material_phaseMemberAt2(grainID,ce)) + C = phase_homogenizedC(material_phaseID(grainID,ce),material_phaseEntry(grainID,ce)) equivalentMu = lattice_equivalent_mu(C,'voigt') end function equivalentMu @@ -661,14 +661,14 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa !> @brief calculating the grain deformation gradient (the same with ! homogenization_RGC_partitionDeformation, but used only for perturbation scheme) !------------------------------------------------------------------------------------------------- - subroutine grainDeformation(F, avgF, ho, me) + subroutine grainDeformation(F, avgF, ho, en) real(pReal), dimension(:,:,:), intent(out) :: F !< partitioned F per grain real(pReal), dimension(:,:), intent(in) :: avgF !< averaged F integer, intent(in) :: & ho, & - me + en real(pReal), dimension(3) :: aVect,nVect integer, dimension(4) :: intFace @@ -685,8 +685,8 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa iGrain3 = grain1to3(iGrain,prm%N_constituents) do iFace = 1,6 intFace = getInterface(iFace,iGrain3) - aVect = relaxationVector(intFace,ho,me) - nVect = interfaceNormal(intFace,ho,me) + aVect = relaxationVector(intFace,ho,en) + nVect = interfaceNormal(intFace,ho,en) forall (i=1:3,j=1:3) & F(i,j,iGrain) = F(i,j,iGrain) + aVect(i)*nVect(j) ! effective relaxations enddo @@ -753,11 +753,11 @@ end subroutine mechanical_RGC_results !-------------------------------------------------------------------------------------------------- !> @brief collect relaxation vectors of an interface !-------------------------------------------------------------------------------------------------- -pure function relaxationVector(intFace,ho,me) +pure function relaxationVector(intFace,ho,en) real(pReal), dimension (3) :: relaxationVector - integer, intent(in) :: ho,me + integer, intent(in) :: ho,en integer, dimension(4), intent(in) :: intFace !< set of interface ID in 4D array (normal and position) integer :: iNum @@ -770,7 +770,7 @@ pure function relaxationVector(intFace,ho,me) iNum = interface4to1(intFace,prm%N_constituents) ! identify the position of the interface in global state array if (iNum > 0) then - relaxationVector = stt%relaxationVector((3*iNum-2):(3*iNum),me) + relaxationVector = stt%relaxationVector((3*iNum-2):(3*iNum),en) else relaxationVector = 0.0_pReal endif @@ -783,14 +783,14 @@ end function relaxationVector !-------------------------------------------------------------------------------------------------- !> @brief identify the normal of an interface !-------------------------------------------------------------------------------------------------- -pure function interfaceNormal(intFace,ho,me) +pure function interfaceNormal(intFace,ho,en) real(pReal), dimension(3) :: interfaceNormal integer, dimension(4), intent(in) :: intFace !< interface ID in 4D array (normal and position) integer, intent(in) :: & ho, & - me + en integer :: nPos associate (dst => dependentState(ho)) @@ -801,7 +801,7 @@ pure function interfaceNormal(intFace,ho,me) nPos = abs(intFace(1)) ! identify the position of the interface in global state array interfaceNormal(nPos) = real(intFace(1)/abs(intFace(1)),pReal) ! get the normal vector w.r.t. cluster axis - interfaceNormal = matmul(dst%orientation(1:3,1:3,me),interfaceNormal) ! map the normal vector into sample coordinate system (basis) + interfaceNormal = matmul(dst%orientation(1:3,1:3,en),interfaceNormal) ! map the normal vector into sample coordinate system (basis) end associate diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index 7602e50d2..a37b9ef67 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -44,8 +44,8 @@ module subroutine thermal_init() allocate(current(configHomogenizations%length)) do ho = 1, configHomogenizations%length - allocate(current(ho)%T(count(material_homogenizationAt2==ho)), source=300.0_pReal) - allocate(current(ho)%dot_T(count(material_homogenizationAt2==ho)), source=0.0_pReal) + allocate(current(ho)%T(count(material_homogenizationID==ho)), source=300.0_pReal) + allocate(current(ho)%dot_T(count(material_homogenizationID==ho)), source=0.0_pReal) configHomogenization => configHomogenizations%get(ho) associate(prm => param(ho)) if (configHomogenization%contains('thermal')) then @@ -75,9 +75,9 @@ module subroutine thermal_partition(ce) integer :: co - T = current(material_homogenizationAt2(ce))%T(material_homogenizationMemberAt2(ce)) - dot_T = current(material_homogenizationAt2(ce))%dot_T(material_homogenizationMemberAt2(ce)) - do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce)) + T = current(material_homogenizationID(ce))%T(material_homogenizationEntry(ce)) + dot_T = current(material_homogenizationID(ce))%dot_T(material_homogenizationEntry(ce)) + do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) call phase_thermal_setField(T,dot_T,co,ce) enddo @@ -109,11 +109,11 @@ module function thermal_conduction_getConductivity(ce) result(K) K = 0.0_pReal - do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce)) - K = K + crystallite_push33ToRef(co,ce,lattice_K(:,:,material_phaseAt2(co,ce))) + do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) + K = K + crystallite_push33ToRef(co,ce,lattice_K(:,:,material_phaseID(co,ce))) enddo - K = K / real(homogenization_Nconstituents(material_homogenizationAt2(ce)),pReal) + K = K / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) end function thermal_conduction_getConductivity @@ -131,11 +131,11 @@ module function thermal_conduction_getSpecificHeat(ce) result(c_P) c_P = 0.0_pReal - do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce)) - c_P = c_P + lattice_c_p(material_phaseAt2(co,ce)) + do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) + c_P = c_P + lattice_c_p(material_phaseID(co,ce)) enddo - c_P = c_P / real(homogenization_Nconstituents(material_homogenizationAt2(ce)),pReal) + c_P = c_P / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) end function thermal_conduction_getSpecificHeat @@ -153,11 +153,11 @@ module function thermal_conduction_getMassDensity(ce) result(rho) rho = 0.0_pReal - do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce)) - rho = rho + lattice_rho(material_phaseAt2(co,ce)) + do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) + rho = rho + lattice_rho(material_phaseID(co,ce)) enddo - rho = rho / real(homogenization_Nconstituents(material_homogenizationAt2(ce)),pReal) + rho = rho / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) end function thermal_conduction_getMassDensity @@ -172,8 +172,8 @@ module subroutine homogenization_thermal_setField(T,dot_T, ce) real(pReal), intent(in) :: T, dot_T - current(material_homogenizationAt2(ce))%T(material_homogenizationMemberAt2(ce)) = T - current(material_homogenizationAt2(ce))%dot_T(material_homogenizationMemberAt2(ce)) = dot_T + current(material_homogenizationID(ce))%T(material_homogenizationEntry(ce)) = T + current(material_homogenizationID(ce))%dot_T(material_homogenizationEntry(ce)) = dot_T end subroutine homogenization_thermal_setField @@ -207,7 +207,7 @@ module function homogenization_thermal_T(ce) result(T) integer, intent(in) :: ce real(pReal) :: T - T = current(material_homogenizationAt2(ce))%T(material_homogenizationMemberAt2(ce)) + T = current(material_homogenizationID(ce))%T(material_homogenizationEntry(ce)) end function homogenization_thermal_T diff --git a/src/material.f90 b/src/material.f90 index aecfaa1dd..6575872ed 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -28,14 +28,14 @@ module material integer, dimension(:), allocatable, public, protected :: & ! (elem) material_homogenizationAt, & !< homogenization ID of each element - material_homogenizationAt2, & !< per cell - material_homogenizationMemberAt2 !< cell + material_homogenizationID, & !< per cell + material_homogenizationEntry !< cell integer, dimension(:,:), allocatable :: & ! (ip,elem) material_homogenizationMemberAt !< position of the element within its homogenization instance integer, dimension(:,:), allocatable, public, protected :: & ! (constituent,elem) material_phaseAt, & !< phase ID of each element - material_phaseAt2, & !< per constituent,cell - material_phaseMemberAt2 !< per constituent, cell + material_phaseID, & !< per constituent,cell + material_phaseEntry !< per constituent, cell integer, dimension(:,:,:), allocatable, public, protected :: & ! (constituent,IP,elem) material_phaseMemberAt !< position of the element within its phase instance @@ -117,10 +117,10 @@ subroutine material_parseMaterial allocate(material_phaseMemberAt(homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems),source=0) - allocate(material_homogenizationAt2(discretization_nIPs*discretization_Nelems),source=0) - allocate(material_homogenizationMemberAt2(discretization_nIPs*discretization_Nelems),source=0) - allocate(material_phaseAt2(homogenization_maxNconstituents,discretization_nIPs*discretization_Nelems),source=0) - allocate(material_phaseMemberAt2(homogenization_maxNconstituents,discretization_nIPs*discretization_Nelems),source=0) + allocate(material_homogenizationID(discretization_nIPs*discretization_Nelems),source=0) + allocate(material_homogenizationEntry(discretization_nIPs*discretization_Nelems),source=0) + allocate(material_phaseID(homogenization_maxNconstituents,discretization_nIPs*discretization_Nelems),source=0) + allocate(material_phaseEntry(homogenization_maxNconstituents,discretization_nIPs*discretization_Nelems),source=0) do el = 1, discretization_Nelems material => materials%get(discretization_materialAt(el)) @@ -131,8 +131,8 @@ subroutine material_parseMaterial ce = (el-1)*discretization_nIPs + ip counterHomogenization(material_homogenizationAt(el)) = counterHomogenization(material_homogenizationAt(el)) + 1 material_homogenizationMemberAt(ip,el) = counterHomogenization(material_homogenizationAt(el)) - material_homogenizationAt2(ce) = material_homogenizationAt(el) - material_homogenizationMemberAt2(ce) = material_homogenizationMemberAt(ip,el) + material_homogenizationID(ce) = material_homogenizationAt(el) + material_homogenizationEntry(ce) = material_homogenizationMemberAt(ip,el) enddo frac = 0.0_pReal @@ -146,8 +146,8 @@ subroutine material_parseMaterial counterPhase(material_phaseAt(co,el)) = counterPhase(material_phaseAt(co,el)) + 1 material_phaseMemberAt(co,ip,el) = counterPhase(material_phaseAt(co,el)) - material_phaseAt2(co,ce) = material_phaseAt(co,el) - material_phaseMemberAt2(co,ce) = material_phaseMemberAt(co,ip,el) + material_phaseID(co,ce) = material_phaseAt(co,el) + material_phaseEntry(co,ce) = material_phaseMemberAt(co,ip,el) enddo enddo diff --git a/src/phase.f90 b/src/phase.f90 index cb5845318..efb2862e2 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -419,10 +419,10 @@ subroutine phase_restore(ce,includeL) co - do co = 1,homogenization_Nconstituents(material_homogenizationAt2(ce)) - if (damageState(material_phaseAt2(co,ce))%sizeState > 0) & - damageState(material_phaseAt2(co,ce))%state( :,material_phasememberAt2(co,ce)) = & - damageState(material_phaseAt2(co,ce))%state0(:,material_phasememberAt2(co,ce)) + do co = 1,homogenization_Nconstituents(material_homogenizationID(ce)) + if (damageState(material_phaseID(co,ce))%sizeState > 0) & + damageState(material_phaseID(co,ce))%state( :,material_phaseEntry(co,ce)) = & + damageState(material_phaseID(co,ce))%state0(:,material_phaseEntry(co,ce)) enddo call mechanical_restore(ce,includeL) @@ -473,7 +473,6 @@ subroutine crystallite_init() integer :: & ph, & - me, & co, & !< counter in integration point component loop ip, & !< counter in integration point loop el, & !< counter in element loop @@ -539,12 +538,10 @@ subroutine crystallite_init() flush(IO_STDOUT) - !$OMP PARALLEL DO PRIVATE(ph,me) + !$OMP PARALLEL DO do el = 1, size(material_phaseMemberAt,3) do ip = 1, size(material_phaseMemberAt,2) do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) - ph = material_phaseAt(co,el) - me = material_phaseMemberAt(co,ip,el) call crystallite_orientations(co,ip,el) call plastic_dependentState(co,ip,el) ! update dependent state variables to be consistent with basic states enddo @@ -590,11 +587,11 @@ function crystallite_push33ToRef(co,ce, tensor33) real(pReal), dimension(3,3) :: crystallite_push33ToRef real(pReal), dimension(3,3) :: T - integer :: ph, me + integer :: ph, en - ph = material_phaseAt2(co,ce) - me = material_phaseMemberAt2(co,ce) - T = matmul(material_orientation0(co,ph,me)%asMatrix(),transpose(math_inv33(phase_mechanical_getF(co,ce)))) ! ToDo: initial orientation correct? + ph = material_phaseID(co,ce) + en = material_phaseEntry(co,ce) + T = matmul(material_orientation0(co,ph,en)%asMatrix(),transpose(math_inv33(phase_mechanical_getF(co,ce)))) ! ToDo: initial orientation correct? crystallite_push33ToRef = matmul(transpose(T),matmul(tensor33,T)) diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index 9659e5fea..abde56e55 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -151,7 +151,7 @@ module subroutine damage_init do ph = 1,phases%length - Nmembers = count(material_phaseAt2 == ph) + Nmembers = count(material_phaseID == ph) allocate(current(ph)%phi(Nmembers),source=1.0_pReal) allocate(current(ph)%d_phi_d_dot_phi(Nmembers),source=0.0_pReal) @@ -199,9 +199,9 @@ module subroutine phase_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, phiDot = 0.0_pReal dPhiDot_dPhi = 0.0_pReal - do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce)) - ph = material_phaseAt2(co,ce) - me = material_phasememberAt2(co,ce) + do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) + ph = material_phaseID(co,ce) + me = material_phaseEntry(co,ce) select case(phase_source(ph)) case (DAMAGE_ISOBRITTLE_ID) @@ -477,7 +477,7 @@ module subroutine phase_damage_set_phi(phi,co,ce) integer, intent(in) :: ce, co - current(material_phaseAt2(co,ce))%phi(material_phaseMemberAt2(co,ce)) = phi + current(material_phaseID(co,ce))%phi(material_phaseEntry(co,ce)) = phi end subroutine phase_damage_set_phi diff --git a/src/phase_damage_anisoductile.f90 b/src/phase_damage_anisoductile.f90 index f047a5dac..bb2f2bcbc 100644 --- a/src/phase_damage_anisoductile.f90 +++ b/src/phase_damage_anisoductile.f90 @@ -35,7 +35,7 @@ module function anisoductile_init() result(mySources) pl, & sources, & src - integer :: Ninstances,Nmembers,p + integer :: Ninstances,Nmembers,ph integer, dimension(:), allocatable :: N_sl character(len=pStringLen) :: extmsg = '' @@ -50,15 +50,15 @@ module function anisoductile_init() result(mySources) phases => config_material%get('phase') allocate(param(phases%length)) - do p = 1, phases%length - if(mySources(p)) then - phase => phases%get(p) + do ph = 1, phases%length + if(mySources(ph)) then + phase => phases%get(ph) mech => phase%get('mechanical') pl => mech%get('plastic') sources => phase%get('damage') - associate(prm => param(p)) + associate(prm => param(ph)) src => sources%get(1) N_sl = pl%get_as1dInt('N_sl',defaultVal=emptyIntArray) @@ -78,10 +78,10 @@ module function anisoductile_init() result(mySources) if (prm%q <= 0.0_pReal) extmsg = trim(extmsg)//' q' if (any(prm%gamma_crit < 0.0_pReal)) extmsg = trim(extmsg)//' gamma_crit' - Nmembers=count(material_phaseAt2==p) - call phase_allocateState(damageState(p),Nmembers,1,1,0) - damageState(p)%atol = src%get_asFloat('anisoDuctile_atol',defaultVal=1.0e-3_pReal) - if(any(damageState(p)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' anisoductile_atol' + Nmembers=count(material_phaseID==ph) + call phase_allocateState(damageState(ph),Nmembers,1,1,0) + damageState(ph)%atol = src%get_asFloat('anisoDuctile_atol',defaultVal=1.0e-3_pReal) + if(any(damageState(ph)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' anisoductile_atol' end associate diff --git a/src/phase_damage_isobrittle.f90 b/src/phase_damage_isobrittle.f90 index 3c7866e66..25fe1d99a 100644 --- a/src/phase_damage_isobrittle.f90 +++ b/src/phase_damage_isobrittle.f90 @@ -31,7 +31,7 @@ module function isobrittle_init() result(mySources) phase, & sources, & src - integer :: Nmembers,p + integer :: Nmembers,ph character(len=pStringLen) :: extmsg = '' @@ -45,12 +45,12 @@ module function isobrittle_init() result(mySources) phases => config_material%get('phase') allocate(param(phases%length)) - do p = 1, phases%length - if(mySources(p)) then - phase => phases%get(p) + do ph = 1, phases%length + if(mySources(ph)) then + phase => phases%get(ph) sources => phase%get('damage') - associate(prm => param(p)) + associate(prm => param(ph)) src => sources%get(1) prm%W_crit = src%get_asFloat('W_crit') @@ -64,10 +64,10 @@ module function isobrittle_init() result(mySources) ! sanity checks if (prm%W_crit <= 0.0_pReal) extmsg = trim(extmsg)//' W_crit' - Nmembers = count(material_phaseAt2==p) - call phase_allocateState(damageState(p),Nmembers,1,1,1) - damageState(p)%atol = src%get_asFloat('isoBrittle_atol',defaultVal=1.0e-3_pReal) - if(any(damageState(p)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' isobrittle_atol' + Nmembers = count(material_phaseID==ph) + call phase_allocateState(damageState(ph),Nmembers,1,1,1) + damageState(ph)%atol = src%get_asFloat('isoBrittle_atol',defaultVal=1.0e-3_pReal) + if(any(damageState(ph)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' isobrittle_atol' end associate diff --git a/src/phase_damage_isoductile.f90 b/src/phase_damage_isoductile.f90 index b5ca9a1c2..5a9d521e4 100644 --- a/src/phase_damage_isoductile.f90 +++ b/src/phase_damage_isoductile.f90 @@ -33,7 +33,7 @@ module function isoductile_init() result(mySources) phase, & sources, & src - integer :: Ninstances,Nmembers,p + integer :: Ninstances,Nmembers,ph character(len=pStringLen) :: extmsg = '' @@ -47,12 +47,12 @@ module function isoductile_init() result(mySources) phases => config_material%get('phase') allocate(param(phases%length)) - do p = 1, phases%length - if(mySources(p)) then - phase => phases%get(p) + do ph = 1, phases%length + if(mySources(ph)) then + phase => phases%get(ph) sources => phase%get('damage') - associate(prm => param(p)) + associate(prm => param(ph)) src => sources%get(1) prm%q = src%get_asFloat('q') @@ -68,10 +68,10 @@ module function isoductile_init() result(mySources) if (prm%q <= 0.0_pReal) extmsg = trim(extmsg)//' q' if (prm%gamma_crit <= 0.0_pReal) extmsg = trim(extmsg)//' gamma_crit' - Nmembers=count(material_phaseAt2==p) - call phase_allocateState(damageState(p),Nmembers,1,1,0) - damageState(p)%atol = src%get_asFloat('isoDuctile_atol',defaultVal=1.0e-3_pReal) - if(any(damageState(p)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' isoductile_atol' + Nmembers=count(material_phaseID==ph) + call phase_allocateState(damageState(ph),Nmembers,1,1,0) + damageState(ph)%atol = src%get_asFloat('isoDuctile_atol',defaultVal=1.0e-3_pReal) + if(any(damageState(ph)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' isoductile_atol' end associate diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index e8cf406ef..0664484d7 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -1217,9 +1217,9 @@ module subroutine mechanical_restore(ce,includeL) co, ph, me - do co = 1,homogenization_Nconstituents(material_homogenizationAt2(ce)) - ph = material_phaseAt2(co,ce) - me = material_phaseMemberAt2(co,ce) + do co = 1,homogenization_Nconstituents(material_homogenizationID(ce)) + ph = material_phaseID(co,ce) + me = material_phaseEntry(co,ce) if (includeL) then phase_mechanical_Lp(ph)%data(1:3,1:3,me) = phase_mechanical_Lp0(ph)%data(1:3,1:3,me) phase_mechanical_Li(ph)%data(1:3,1:3,me) = phase_mechanical_Li0(ph)%data(1:3,1:3,me) @@ -1267,8 +1267,8 @@ module function phase_mechanical_dPdF(dt,co,ce) result(dPdF) logical :: error - ph = material_phaseAt2(co,ce) - me = material_phaseMemberAt2(co,ce) + ph = material_phaseID(co,ce) + me = material_phaseEntry(co,ce) call phase_hooke_SandItsTangents(devNull,dSdFe,dSdFi, & phase_mechanical_Fe(ph)%data(1:3,1:3,me), & @@ -1432,7 +1432,7 @@ module function phase_mechanical_getF(co,ce) result(F) real(pReal), dimension(3,3) :: F - F = phase_mechanical_F(material_phaseAt2(co,ce))%data(1:3,1:3,material_phaseMemberAt2(co,ce)) + F = phase_mechanical_F(material_phaseID(co,ce))%data(1:3,1:3,material_phaseEntry(co,ce)) end function phase_mechanical_getF @@ -1461,7 +1461,7 @@ module function phase_mechanical_getP(co,ce) result(P) real(pReal), dimension(3,3) :: P - P = phase_mechanical_P(material_phaseAt2(co,ce))%data(1:3,1:3,material_phaseMemberAt2(co,ce)) + P = phase_mechanical_P(material_phaseID(co,ce))%data(1:3,1:3,material_phaseEntry(co,ce)) end function phase_mechanical_getP @@ -1473,7 +1473,7 @@ module subroutine phase_mechanical_setF(F,co,ce) integer, intent(in) :: co, ce - phase_mechanical_F(material_phaseAt2(co,ce))%data(1:3,1:3,material_phaseMemberAt2(co,ce)) = F + phase_mechanical_F(material_phaseID(co,ce))%data(1:3,1:3,material_phaseEntry(co,ce)) = F end subroutine phase_mechanical_setF diff --git a/src/phase_mechanical_plastic_dislotungsten.f90 b/src/phase_mechanical_plastic_dislotungsten.f90 index b7ade48a8..2e7130756 100644 --- a/src/phase_mechanical_plastic_dislotungsten.f90 +++ b/src/phase_mechanical_plastic_dislotungsten.f90 @@ -220,7 +220,7 @@ module function plastic_dislotungsten_init() result(myPlasticity) !-------------------------------------------------------------------------------------------------- ! allocate state arrays - Nmembers = count(material_phaseAt2 == ph) + Nmembers = count(material_phaseID == ph) sizeDotState = size(['rho_mob ','rho_dip ','gamma_sl']) * prm%sum_N_sl sizeState = sizeDotState diff --git a/src/phase_mechanical_plastic_dislotwin.f90 b/src/phase_mechanical_plastic_dislotwin.f90 index 1e67db59e..43be614ac 100644 --- a/src/phase_mechanical_plastic_dislotwin.f90 +++ b/src/phase_mechanical_plastic_dislotwin.f90 @@ -406,7 +406,7 @@ module function plastic_dislotwin_init() result(myPlasticity) !-------------------------------------------------------------------------------------------------- ! allocate state arrays - Nmembers = count(material_phaseAt2 == ph) + Nmembers = count(material_phaseID == ph) sizeDotState = size(['rho_mob ','rho_dip ','gamma_sl']) * prm%sum_N_sl & + size(['f_tw']) * prm%sum_N_tw & + size(['f_tr']) * prm%sum_N_tr diff --git a/src/phase_mechanical_plastic_isotropic.f90 b/src/phase_mechanical_plastic_isotropic.f90 index 5a37369f0..548e2fd75 100644 --- a/src/phase_mechanical_plastic_isotropic.f90 +++ b/src/phase_mechanical_plastic_isotropic.f90 @@ -119,7 +119,7 @@ module function plastic_isotropic_init() result(myPlasticity) !-------------------------------------------------------------------------------------------------- ! allocate state arrays - Nmembers = count(material_phaseAt2 == ph) + Nmembers = count(material_phaseID == ph) sizeDotState = size(['xi ','gamma']) sizeState = sizeDotState diff --git a/src/phase_mechanical_plastic_kinehardening.f90 b/src/phase_mechanical_plastic_kinehardening.f90 index 0c02e11db..936a7f884 100644 --- a/src/phase_mechanical_plastic_kinehardening.f90 +++ b/src/phase_mechanical_plastic_kinehardening.f90 @@ -165,7 +165,7 @@ module function plastic_kinehardening_init() result(myPlasticity) !-------------------------------------------------------------------------------------------------- ! allocate state arrays - Nmembers = count(material_phaseAt2 == ph) + Nmembers = count(material_phaseID == ph) sizeDotState = size(['crss ','crss_back', 'accshear ']) * prm%sum_N_sl !ToDo: adjust names like in material.yaml sizeDeltaState = size(['sense ', 'chi0 ', 'gamma0' ]) * prm%sum_N_sl !ToDo: adjust names like in material.yaml sizeState = sizeDotState + sizeDeltaState diff --git a/src/phase_mechanical_plastic_none.f90 b/src/phase_mechanical_plastic_none.f90 index 28e9fbc7c..544de31b1 100644 --- a/src/phase_mechanical_plastic_none.f90 +++ b/src/phase_mechanical_plastic_none.f90 @@ -30,7 +30,7 @@ module function plastic_none_init() result(myPlasticity) phases => config_material%get('phase') do ph = 1, phases%length if(.not. myPlasticity(ph)) cycle - call phase_allocateState(plasticState(ph),count(material_phaseAt2 == ph),0,0,0) + call phase_allocateState(plasticState(ph),count(material_phaseID == ph),0,0,0) enddo end function plastic_none_init diff --git a/src/phase_mechanical_plastic_nonlocal.f90 b/src/phase_mechanical_plastic_nonlocal.f90 index d86f7dc7e..ba7f76881 100644 --- a/src/phase_mechanical_plastic_nonlocal.f90 +++ b/src/phase_mechanical_plastic_nonlocal.f90 @@ -398,7 +398,7 @@ module function plastic_nonlocal_init() result(myPlasticity) !-------------------------------------------------------------------------------------------------- ! allocate state arrays - Nmembers = count(material_phaseAt2 == ph) + Nmembers = count(material_phaseID == ph) sizeDotState = size([ 'rhoSglEdgePosMobile ','rhoSglEdgeNegMobile ', & 'rhoSglScrewPosMobile ','rhoSglScrewNegMobile ', & 'rhoSglEdgePosImmobile ','rhoSglEdgeNegImmobile ', & @@ -527,7 +527,7 @@ module function plastic_nonlocal_init() result(myPlasticity) if(.not. myPlasticity(ph)) cycle phase => phases%get(ph) - Nmembers = count(material_phaseAt2 == ph) + Nmembers = count(material_phaseID == ph) l = 0 do t = 1,4 do s = 1,param(ph)%sum_N_sl @@ -1824,9 +1824,9 @@ subroutine storeGeometry(ph) V = reshape(IPvolume,[product(shape(IPvolume))]) - do ce = 1, size(material_homogenizationMemberAt2,1) + do ce = 1, size(material_homogenizationEntry,1) do co = 1, homogenization_maxNconstituents - if (material_phaseAt2(co,ce) == ph) geom(ph)%V_0(material_phaseMemberAt2(co,ce)) = V(ce) + if (material_phaseID(co,ce) == ph) geom(ph)%V_0(material_phaseEntry(co,ce)) = V(ce) enddo enddo diff --git a/src/phase_mechanical_plastic_phenopowerlaw.f90 b/src/phase_mechanical_plastic_phenopowerlaw.f90 index 6be46f6a1..77c47907f 100644 --- a/src/phase_mechanical_plastic_phenopowerlaw.f90 +++ b/src/phase_mechanical_plastic_phenopowerlaw.f90 @@ -223,7 +223,7 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) !-------------------------------------------------------------------------------------------------- ! allocate state arrays - Nmembers = count(material_phaseAt2 == ph) + Nmembers = count(material_phaseID == ph) sizeDotState = size(['xi_sl ','gamma_sl']) * prm%sum_N_sl & + size(['xi_tw ','gamma_tw']) * prm%sum_N_tw sizeState = sizeDotState diff --git a/src/phase_thermal.f90 b/src/phase_thermal.f90 index 21ec93c9c..1e157f338 100644 --- a/src/phase_thermal.f90 +++ b/src/phase_thermal.f90 @@ -89,7 +89,7 @@ module subroutine thermal_init(phases) allocate(thermal_Nsources(phases%length),source = 0) do ph = 1, phases%length - Nmembers = count(material_phaseAt2 == ph) + Nmembers = count(material_phaseID == ph) allocate(current(ph)%T(Nmembers),source=300.0_pReal) allocate(current(ph)%dot_T(Nmembers),source=0.0_pReal) phase => phases%get(ph) @@ -268,8 +268,8 @@ module subroutine phase_thermal_setField(T,dot_T, co,ce) integer, intent(in) :: ce, co - current(material_phaseAt2(co,ce))%T(material_phaseMemberAt2(co,ce)) = T - current(material_phaseAt2(co,ce))%dot_T(material_phaseMemberAt2(co,ce)) = dot_T + current(material_phaseID(co,ce))%T(material_phaseEntry(co,ce)) = T + current(material_phaseID(co,ce))%dot_T(material_phaseEntry(co,ce)) = dot_T end subroutine phase_thermal_setField diff --git a/src/phase_thermal_dissipation.f90 b/src/phase_thermal_dissipation.f90 index d3e7094a1..b16ed3cf7 100644 --- a/src/phase_thermal_dissipation.f90 +++ b/src/phase_thermal_dissipation.f90 @@ -54,7 +54,7 @@ module function dissipation_init(source_length) result(mySources) src => sources%get(so) prm%kappa = src%get_asFloat('kappa') - Nmembers = count(material_phaseAt2 == ph) + Nmembers = count(material_phaseID == ph) call phase_allocateState(thermalState(ph)%p(so),Nmembers,0,0,0) end associate diff --git a/src/phase_thermal_externalheat.f90 b/src/phase_thermal_externalheat.f90 index 760326044..d5bbc7c38 100644 --- a/src/phase_thermal_externalheat.f90 +++ b/src/phase_thermal_externalheat.f90 @@ -67,7 +67,7 @@ module function externalheat_init(source_length) result(mySources) prm%f_T = src%get_as1dFloat('f_T',requiredSize = size(prm%t_n)) - Nmembers = count(material_phaseAt2 == ph) + Nmembers = count(material_phaseID == ph) call phase_allocateState(thermalState(ph)%p(so),Nmembers,1,1,0) end associate endif From 330803881b7bf42e0151a25204b6da08c23daf0f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 6 Apr 2021 11:41:45 +0200 Subject: [PATCH 124/219] variable 'damage' is not occupied anymore --- src/phase_damage.f90 | 4 ++-- src/phase_damage_anisobrittle.f90 | 2 +- src/phase_damage_anisoductile.f90 | 2 +- src/phase_damage_isobrittle.f90 | 2 +- src/phase_damage_isoductile.f90 | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index abde56e55..4397d5cad 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -1,7 +1,7 @@ !---------------------------------------------------------------------------------------------------- !> @brief internal microstructure state for all damage sources and kinematics constitutive models !---------------------------------------------------------------------------------------------------- -submodule(phase) damagee +submodule(phase) damage enum, bind(c); enumerator :: & DAMAGE_UNDEFINED_ID, & DAMAGE_ISOBRITTLE_ID, & @@ -520,4 +520,4 @@ module subroutine damage_forward() end subroutine damage_forward -end submodule damagee +end submodule damage diff --git a/src/phase_damage_anisobrittle.f90 b/src/phase_damage_anisobrittle.f90 index 3c573f33a..7e5f79e17 100644 --- a/src/phase_damage_anisobrittle.f90 +++ b/src/phase_damage_anisobrittle.f90 @@ -4,7 +4,7 @@ !> @brief material subroutine incorporating anisotropic brittle damage source mechanism !> @details to be done !-------------------------------------------------------------------------------------------------- -submodule (phase:damagee) anisobrittle +submodule (phase:damage) anisobrittle type :: tParameters !< container type for internal constitutive parameters real(pReal) :: & diff --git a/src/phase_damage_anisoductile.f90 b/src/phase_damage_anisoductile.f90 index bb2f2bcbc..54b63278f 100644 --- a/src/phase_damage_anisoductile.f90 +++ b/src/phase_damage_anisoductile.f90 @@ -4,7 +4,7 @@ !> @brief material subroutine incorporating anisotropic ductile damage source mechanism !> @details to be done !-------------------------------------------------------------------------------------------------- -submodule(phase:damagee) anisoductile +submodule(phase:damage) anisoductile type :: tParameters !< container type for internal constitutive parameters real(pReal) :: & diff --git a/src/phase_damage_isobrittle.f90 b/src/phase_damage_isobrittle.f90 index 25fe1d99a..59cedb554 100644 --- a/src/phase_damage_isobrittle.f90 +++ b/src/phase_damage_isobrittle.f90 @@ -4,7 +4,7 @@ !> @brief material subroutine incoprorating isotropic brittle damage source mechanism !> @details to be done !-------------------------------------------------------------------------------------------------- -submodule(phase:damagee) isobrittle +submodule(phase:damage) isobrittle type :: tParameters !< container type for internal constitutive parameters real(pReal) :: & diff --git a/src/phase_damage_isoductile.f90 b/src/phase_damage_isoductile.f90 index 5a9d521e4..1f1bba847 100644 --- a/src/phase_damage_isoductile.f90 +++ b/src/phase_damage_isoductile.f90 @@ -4,7 +4,7 @@ !> @brief material subroutine incorporating isotropic ductile damage source mechanism !> @details to be done !-------------------------------------------------------------------------------------------------- -submodule(phase:damagee) isoductile +submodule(phase:damage) isoductile type:: tParameters !< container type for internal constitutive parameters real(pReal) :: & From 49804c6e44d84a3d835d8bda4082d4ee502c2caf Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 6 Apr 2021 11:55:30 +0200 Subject: [PATCH 125/219] preparing split --- src/commercialFEM_fileList.f90 | 3 +++ src/homogenization_damage.f90 | 11 +++++++++-- src/homogenization_damage_pass.f90 | 14 ++++++++++++++ src/homogenization_thermal.f90 | 10 ++++++++++ src/homogenization_thermal_isotemperature.f90 | 14 ++++++++++++++ src/homogenization_thermal_pass.f90 | 14 ++++++++++++++ 6 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 src/homogenization_damage_pass.f90 create mode 100644 src/homogenization_thermal_isotemperature.f90 create mode 100644 src/homogenization_thermal_pass.f90 diff --git a/src/commercialFEM_fileList.f90 b/src/commercialFEM_fileList.f90 index 585f242b5..1eac4f8fc 100644 --- a/src/commercialFEM_fileList.f90 +++ b/src/commercialFEM_fileList.f90 @@ -47,5 +47,8 @@ #include "homogenization_mechanical_isostrain.f90" #include "homogenization_mechanical_RGC.f90" #include "homogenization_thermal.f90" +#include "homogenization_thermal_pass.f90" +#include "homogenization_thermal_isotemperature.f90" #include "homogenization_damage.f90" +#include "homogenization_damage_pass.f90" #include "CPFEM.f90" diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index 203c45670..94978ccc8 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -1,10 +1,17 @@ !-------------------------------------------------------------------------------------------------- !> @author Martin Diehl, KU Leuven !-------------------------------------------------------------------------------------------------- -submodule(homogenization) homogenization_damage +submodule(homogenization) damage use lattice + interface + + module subroutine pass_init + end subroutine pass_init + + end interface + type :: tDataContainer real(pReal), dimension(:), allocatable :: phi end type tDataContainer @@ -165,4 +172,4 @@ module subroutine damage_nonlocal_results(ho,group) end subroutine damage_nonlocal_results -end submodule homogenization_damage +end submodule damage diff --git a/src/homogenization_damage_pass.f90 b/src/homogenization_damage_pass.f90 new file mode 100644 index 000000000..bda2702f7 --- /dev/null +++ b/src/homogenization_damage_pass.f90 @@ -0,0 +1,14 @@ +!-------------------------------------------------------------------------------------------------- +!> @author Martin Diehl, KU Leuven +!> @brief Dummy homogenization scheme for 1 constituent per material point +!-------------------------------------------------------------------------------------------------- +submodule(homogenization:damage) pass + +contains + +module subroutine pass_init + + +end subroutine pass_init + +end submodule pass diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index a37b9ef67..00cb438d1 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -5,6 +5,16 @@ submodule(homogenization) thermal use lattice + interface + + module subroutine pass_init + end subroutine pass_init + + module subroutine isothermal_init + end subroutine isothermal_init + + end interface + type :: tDataContainer real(pReal), dimension(:), allocatable :: T, dot_T end type tDataContainer diff --git a/src/homogenization_thermal_isotemperature.f90 b/src/homogenization_thermal_isotemperature.f90 new file mode 100644 index 000000000..7358ecf08 --- /dev/null +++ b/src/homogenization_thermal_isotemperature.f90 @@ -0,0 +1,14 @@ +!-------------------------------------------------------------------------------------------------- +!> @author Martin Diehl, KU Leuven +!> @brief Dummy homogenization scheme for 1 constituent per material point +!-------------------------------------------------------------------------------------------------- +submodule(homogenization:thermal) isotemperature + +contains + +module subroutine isotemperature_init + + +end subroutine isotemperature_init + +end submodule isotemperature diff --git a/src/homogenization_thermal_pass.f90 b/src/homogenization_thermal_pass.f90 new file mode 100644 index 000000000..73150b988 --- /dev/null +++ b/src/homogenization_thermal_pass.f90 @@ -0,0 +1,14 @@ +!-------------------------------------------------------------------------------------------------- +!> @author Martin Diehl, KU Leuven +!> @brief Dummy homogenization scheme for 1 constituent per material point +!-------------------------------------------------------------------------------------------------- +submodule(homogenization:thermal) pass + +contains + +module subroutine pass_init + + +end subroutine pass_init + +end submodule pass From d56f1acf3605b378bafd737f3670faa32cde58c6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 6 Apr 2021 12:05:47 +0200 Subject: [PATCH 126/219] shorter names need to prefix 'pass' to avoid name clashes that result in errors during compilation --- src/homogenization_damage_pass.f90 | 4 +- src/homogenization_mechanical.f90 | 54 ++++++++++----------- src/homogenization_mechanical_RGC.f90 | 22 ++++----- src/homogenization_mechanical_isostrain.f90 | 14 +++--- src/homogenization_mechanical_pass.f90 | 10 ++-- src/homogenization_thermal_pass.f90 | 4 +- 6 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/homogenization_damage_pass.f90 b/src/homogenization_damage_pass.f90 index bda2702f7..cbb7ec79f 100644 --- a/src/homogenization_damage_pass.f90 +++ b/src/homogenization_damage_pass.f90 @@ -2,7 +2,7 @@ !> @author Martin Diehl, KU Leuven !> @brief Dummy homogenization scheme for 1 constituent per material point !-------------------------------------------------------------------------------------------------- -submodule(homogenization:damage) pass +submodule(homogenization:damage) damage_pass contains @@ -11,4 +11,4 @@ module subroutine pass_init end subroutine pass_init -end submodule pass +end submodule damage_pass diff --git a/src/homogenization_mechanical.f90 b/src/homogenization_mechanical.f90 index 35ec37f34..954aac403 100644 --- a/src/homogenization_mechanical.f90 +++ b/src/homogenization_mechanical.f90 @@ -7,51 +7,51 @@ submodule(homogenization) mechanical interface - module subroutine mechanical_pass_init - end subroutine mechanical_pass_init + module subroutine pass_init + end subroutine pass_init - module subroutine mechanical_isostrain_init - end subroutine mechanical_isostrain_init + module subroutine isostrain_init + end subroutine isostrain_init - module subroutine mechanical_RGC_init(num_homogMech) + module subroutine RGC_init(num_homogMech) class(tNode), pointer, intent(in) :: & num_homogMech !< pointer to mechanical homogenization numerics data - end subroutine mechanical_RGC_init + end subroutine RGC_init - module subroutine mechanical_isostrain_partitionDeformation(F,avgF) + module subroutine isostrain_partitionDeformation(F,avgF) real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point - end subroutine mechanical_isostrain_partitionDeformation + end subroutine isostrain_partitionDeformation - module subroutine mechanical_RGC_partitionDeformation(F,avgF,ce) + module subroutine RGC_partitionDeformation(F,avgF,ce) real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point integer, intent(in) :: & ce - end subroutine mechanical_RGC_partitionDeformation + end subroutine RGC_partitionDeformation - module subroutine mechanical_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho) + module subroutine isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho) real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses integer, intent(in) :: ho - end subroutine mechanical_isostrain_averageStressAndItsTangent + end subroutine isostrain_averageStressAndItsTangent - module subroutine mechanical_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho) + module subroutine RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho) real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses integer, intent(in) :: ho - end subroutine mechanical_RGC_averageStressAndItsTangent + end subroutine RGC_averageStressAndItsTangent - module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHappy) + module function RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHappy) logical, dimension(2) :: doneAndHappy real(pReal), dimension(:,:,:), intent(in) :: & P,& !< partitioned stresses @@ -61,13 +61,13 @@ submodule(homogenization) mechanical real(pReal), intent(in) :: dt !< time increment integer, intent(in) :: & ce !< cell - end function mechanical_RGC_updateState + end function RGC_updateState - module subroutine mechanical_RGC_results(ho,group) + module subroutine RGC_results(ho,group) integer, intent(in) :: ho !< homogenization type character(len=*), intent(in) :: group !< group name in HDF5 file - end subroutine mechanical_RGC_results + end subroutine RGC_results end interface @@ -92,9 +92,9 @@ module subroutine mechanical_init(num_homog) allocate(homogenization_P(3,3,discretization_nIPs*discretization_Nelems), source=0.0_pReal) num_homogMech => num_homog%get('mech',defaultVal=emptyDict) - if (any(homogenization_type == HOMOGENIZATION_NONE_ID)) call mechanical_pass_init - if (any(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID)) call mechanical_isostrain_init - if (any(homogenization_type == HOMOGENIZATION_RGC_ID)) call mechanical_RGC_init(num_homogMech) + if (any(homogenization_type == HOMOGENIZATION_NONE_ID)) call pass_init + if (any(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID)) call isostrain_init + if (any(homogenization_type == HOMOGENIZATION_RGC_ID)) call RGC_init(num_homogMech) end subroutine mechanical_init @@ -119,10 +119,10 @@ module subroutine mechanical_partition(subF,ce) Fs(1:3,1:3,1) = subF case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization - call mechanical_isostrain_partitionDeformation(Fs,subF) + call isostrain_partitionDeformation(Fs,subF) case (HOMOGENIZATION_RGC_ID) chosenHomogenization - call mechanical_RGC_partitionDeformation(Fs,subF,ce) + call RGC_partitionDeformation(Fs,subF,ce) end select chosenHomogenization @@ -158,7 +158,7 @@ module subroutine mechanical_homogenize(dt,ce) dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(dt,co,ce) Ps(:,:,co) = phase_mechanical_getP(co,ce) enddo - call mechanical_isostrain_averageStressAndItsTangent(& + call isostrain_averageStressAndItsTangent(& homogenization_P(1:3,1:3,ce), & homogenization_dPdF(1:3,1:3,1:3,1:3,ce),& Ps,dPdFs, & @@ -169,7 +169,7 @@ module subroutine mechanical_homogenize(dt,ce) dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(dt,co,ce) Ps(:,:,co) = phase_mechanical_getP(co,ce) enddo - call mechanical_RGC_averageStressAndItsTangent(& + call RGC_averageStressAndItsTangent(& homogenization_P(1:3,1:3,ce), & homogenization_dPdF(1:3,1:3,1:3,1:3,ce),& Ps,dPdFs, & @@ -206,7 +206,7 @@ module function mechanical_updateState(subdt,subF,ce) result(doneAndHappy) Fs(:,:,co) = phase_mechanical_getF(co,ce) Ps(:,:,co) = phase_mechanical_getP(co,ce) enddo - doneAndHappy = mechanical_RGC_updateState(Ps,Fs,subF,subdt,dPdFs,ce) + doneAndHappy = RGC_updateState(Ps,Fs,subF,subdt,dPdFs,ce) else doneAndHappy = .true. endif @@ -230,7 +230,7 @@ module subroutine mechanical_results(group_base,ho) select case(homogenization_type(ho)) case(HOMOGENIZATION_rgc_ID) - call mechanical_RGC_results(ho,group) + call RGC_results(ho,group) end select diff --git a/src/homogenization_mechanical_RGC.f90 b/src/homogenization_mechanical_RGC.f90 index 366eb7a36..772d1c4f5 100644 --- a/src/homogenization_mechanical_RGC.f90 +++ b/src/homogenization_mechanical_RGC.f90 @@ -71,7 +71,7 @@ contains !-------------------------------------------------------------------------------------------------- !> @brief allocates all necessary fields, reads information from material configuration file !-------------------------------------------------------------------------------------------------- -module subroutine mechanical_RGC_init(num_homogMech) +module subroutine RGC_init(num_homogMech) class(tNode), pointer, intent(in) :: & num_homogMech !< pointer to mechanical homogenization numerics data @@ -152,7 +152,7 @@ module subroutine mechanical_RGC_init(num_homogMech) prm%N_constituents = homogMech%get_as1dInt('cluster_size',requiredSize=3) if (homogenization_Nconstituents(ho) /= product(prm%N_constituents)) & - call IO_error(211,ext_msg='N_constituents (mechanical_RGC)') + call IO_error(211,ext_msg='N_constituents (RGC)') prm%xi_alpha = homogMech%get_asFloat('xi_alpha') prm%c_alpha = homogMech%get_asFloat('c_alpha') @@ -187,13 +187,13 @@ module subroutine mechanical_RGC_init(num_homogMech) enddo -end subroutine mechanical_RGC_init +end subroutine RGC_init !-------------------------------------------------------------------------------------------------- !> @brief partitions the deformation gradient onto the constituents !-------------------------------------------------------------------------------------------------- -module subroutine mechanical_RGC_partitionDeformation(F,avgF,ce) +module subroutine RGC_partitionDeformation(F,avgF,ce) real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned F per grain @@ -227,14 +227,14 @@ module subroutine mechanical_RGC_partitionDeformation(F,avgF,ce) end associate -end subroutine mechanical_RGC_partitionDeformation +end subroutine RGC_partitionDeformation !-------------------------------------------------------------------------------------------------- !> @brief update the internal state of the homogenization scheme and tell whether "done" and ! "happy" with result !-------------------------------------------------------------------------------------------------- -module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHappy) +module function RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHappy) logical, dimension(2) :: doneAndHappy real(pReal), dimension(:,:,:), intent(in) :: & P,& !< partitioned stresses @@ -697,13 +697,13 @@ module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHa end subroutine grainDeformation -end function mechanical_RGC_updateState +end function RGC_updateState !-------------------------------------------------------------------------------------------------- !> @brief derive average stress and stiffness from constituent quantities !-------------------------------------------------------------------------------------------------- -module subroutine mechanical_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho) +module subroutine RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho) real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point @@ -715,13 +715,13 @@ module subroutine mechanical_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dP avgP = sum(P,3) /real(product(param(ho)%N_constituents),pReal) dAvgPdAvgF = sum(dPdF,5)/real(product(param(ho)%N_constituents),pReal) -end subroutine mechanical_RGC_averageStressAndItsTangent +end subroutine RGC_averageStressAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- -module subroutine mechanical_RGC_results(ho,group) +module subroutine RGC_results(ho,group) integer, intent(in) :: ho character(len=*), intent(in) :: group @@ -747,7 +747,7 @@ module subroutine mechanical_RGC_results(ho,group) enddo outputsLoop end associate -end subroutine mechanical_RGC_results +end subroutine RGC_results !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization_mechanical_isostrain.f90 b/src/homogenization_mechanical_isostrain.f90 index e7d4cff4c..9a3704575 100644 --- a/src/homogenization_mechanical_isostrain.f90 +++ b/src/homogenization_mechanical_isostrain.f90 @@ -26,7 +26,7 @@ contains !-------------------------------------------------------------------------------------------------- !> @brief allocates all neccessary fields, reads information from material configuration file !-------------------------------------------------------------------------------------------------- -module subroutine mechanical_isostrain_init +module subroutine isostrain_init integer :: & h, & @@ -56,7 +56,7 @@ module subroutine mechanical_isostrain_init case ('avg') prm%mapping = average_ID case default - call IO_error(211,ext_msg='sum'//' (mechanical_isostrain)') + call IO_error(211,ext_msg='sum'//' (isostrain)') end select Nmaterialpoints = count(material_homogenizationAt == h) @@ -68,13 +68,13 @@ module subroutine mechanical_isostrain_init enddo -end subroutine mechanical_isostrain_init +end subroutine isostrain_init !-------------------------------------------------------------------------------------------------- !> @brief partitions the deformation gradient onto the constituents !-------------------------------------------------------------------------------------------------- -module subroutine mechanical_isostrain_partitionDeformation(F,avgF) +module subroutine isostrain_partitionDeformation(F,avgF) real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient @@ -82,13 +82,13 @@ module subroutine mechanical_isostrain_partitionDeformation(F,avgF) F = spread(avgF,3,size(F,3)) -end subroutine mechanical_isostrain_partitionDeformation +end subroutine isostrain_partitionDeformation !-------------------------------------------------------------------------------------------------- !> @brief derive average stress and stiffness from constituent quantities !-------------------------------------------------------------------------------------------------- -module subroutine mechanical_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho) +module subroutine isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho) real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point @@ -110,6 +110,6 @@ module subroutine mechanical_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvg end associate -end subroutine mechanical_isostrain_averageStressAndItsTangent +end subroutine isostrain_averageStressAndItsTangent end submodule isostrain diff --git a/src/homogenization_mechanical_pass.f90 b/src/homogenization_mechanical_pass.f90 index 6217e6836..23fe74f44 100644 --- a/src/homogenization_mechanical_pass.f90 +++ b/src/homogenization_mechanical_pass.f90 @@ -4,14 +4,14 @@ !> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH !> @brief dummy homogenization homogenization scheme for 1 constituent per material point !-------------------------------------------------------------------------------------------------- -submodule(homogenization:mechanical) none +submodule(homogenization:mechanical) mechanical_pass contains !-------------------------------------------------------------------------------------------------- !> @brief allocates all necessary fields, reads information from material configuration file !-------------------------------------------------------------------------------------------------- -module subroutine mechanical_pass_init +module subroutine pass_init integer :: & Ninstances, & @@ -27,7 +27,7 @@ module subroutine mechanical_pass_init if(homogenization_type(h) /= HOMOGENIZATION_NONE_ID) cycle if(homogenization_Nconstituents(h) /= 1) & - call IO_error(211,ext_msg='N_constituents (mechanical_pass)') + call IO_error(211,ext_msg='N_constituents (pass)') Nmaterialpoints = count(material_homogenizationAt == h) homogState(h)%sizeState = 0 @@ -36,6 +36,6 @@ module subroutine mechanical_pass_init enddo -end subroutine mechanical_pass_init +end subroutine pass_init -end submodule none +end submodule mechanical_pass diff --git a/src/homogenization_thermal_pass.f90 b/src/homogenization_thermal_pass.f90 index 73150b988..940a15024 100644 --- a/src/homogenization_thermal_pass.f90 +++ b/src/homogenization_thermal_pass.f90 @@ -2,7 +2,7 @@ !> @author Martin Diehl, KU Leuven !> @brief Dummy homogenization scheme for 1 constituent per material point !-------------------------------------------------------------------------------------------------- -submodule(homogenization:thermal) pass +submodule(homogenization:thermal) thermal_pass contains @@ -11,4 +11,4 @@ module subroutine pass_init end subroutine pass_init -end submodule pass +end submodule thermal_pass From 0d974648f08a8e2e784b5358e831d951585628bd Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 6 Apr 2021 12:18:48 +0200 Subject: [PATCH 127/219] part of damage, not of eigen --- src/phase.f90 | 8 ++++---- src/phase_damage_anisobrittle.f90 | 4 ++-- src/phase_mechanical_eigen.f90 | 16 ++++++++-------- src/phase_mechanical_eigen_cleavageopening.f90 | 4 ++-- src/phase_mechanical_eigen_slipplaneopening.f90 | 10 +++++----- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/phase.f90 b/src/phase.f90 index efb2862e2..d10df84ba 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -259,7 +259,7 @@ module phase end subroutine plastic_dependentState - module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ph,me) + module subroutine damage_anisobrittle_LiAndItsTangent(Ld, dLd_dTstar, S, ph,me) integer, intent(in) :: ph, me real(pReal), intent(in), dimension(3,3) :: & S @@ -267,9 +267,9 @@ module phase Ld !< damage velocity gradient real(pReal), intent(out), dimension(3,3,3,3) :: & dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor) - end subroutine kinematics_cleavage_opening_LiAndItsTangent + end subroutine damage_anisobrittle_LiAndItsTangent - module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ph,me) + module subroutine damage_isoductile_LiAndItsTangent(Ld, dLd_dTstar, S, ph,me) integer, intent(in) :: ph, me real(pReal), intent(in), dimension(3,3) :: & S @@ -277,7 +277,7 @@ module phase Ld !< damage velocity gradient real(pReal), intent(out), dimension(3,3,3,3) :: & dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor) - end subroutine kinematics_slipplane_opening_LiAndItsTangent + end subroutine damage_isoductile_LiAndItsTangent end interface diff --git a/src/phase_damage_anisobrittle.f90 b/src/phase_damage_anisobrittle.f90 index 7e5f79e17..e9672dd3b 100644 --- a/src/phase_damage_anisobrittle.f90 +++ b/src/phase_damage_anisobrittle.f90 @@ -197,7 +197,7 @@ end subroutine anisobrittle_results !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the velocity gradient !-------------------------------------------------------------------------------------------------- -module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ph,me) +module subroutine damage_anisobrittle_LiAndItsTangent(Ld, dLd_dTstar, S, ph,me) integer, intent(in) :: & ph,me @@ -253,6 +253,6 @@ module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, enddo end associate -end subroutine kinematics_cleavage_opening_LiAndItsTangent +end subroutine damage_anisobrittle_LiAndItsTangent end submodule anisobrittle diff --git a/src/phase_mechanical_eigen.f90 b/src/phase_mechanical_eigen.f90 index 955f6ca5d..3f2aec58c 100644 --- a/src/phase_mechanical_eigen.f90 +++ b/src/phase_mechanical_eigen.f90 @@ -9,13 +9,13 @@ submodule(phase:mechanical) eigen model_damage interface - module function kinematics_cleavage_opening_init() result(myKinematics) + module function damage_anisobrittle_init() result(myKinematics) logical, dimension(:), allocatable :: myKinematics - end function kinematics_cleavage_opening_init + end function damage_anisobrittle_init - module function kinematics_slipplane_opening_init() result(myKinematics) + module function damage_isoductile_init() result(myKinematics) logical, dimension(:), allocatable :: myKinematics - end function kinematics_slipplane_opening_init + end function damage_isoductile_init module function thermalexpansion_init(kinematics_length) result(myKinematics) integer, intent(in) :: kinematics_length @@ -70,8 +70,8 @@ module subroutine eigendeformation_init(phases) allocate(model_damage(phases%length), source = KINEMATICS_UNDEFINED_ID) - where(kinematics_cleavage_opening_init()) model_damage = KINEMATICS_cleavage_opening_ID - where(kinematics_slipplane_opening_init()) model_damage = KINEMATICS_slipplane_opening_ID + where(damage_anisobrittle_init()) model_damage = KINEMATICS_cleavage_opening_ID + where(damage_isoductile_init()) model_damage = KINEMATICS_slipplane_opening_ID end subroutine eigendeformation_init @@ -198,12 +198,12 @@ module subroutine phase_LiAndItsTangents(Li, dLi_dS, dLi_dFi, & select case (model_damage(ph)) case (KINEMATICS_cleavage_opening_ID) - call kinematics_cleavage_opening_LiAndItsTangent(my_Li, my_dLi_dS, S, ph, me) + call damage_anisobrittle_LiAndItsTangent(my_Li, my_dLi_dS, S, ph, me) Li = Li + my_Li dLi_dS = dLi_dS + my_dLi_dS active = .true. case (KINEMATICS_slipplane_opening_ID) - call kinematics_slipplane_opening_LiAndItsTangent(my_Li, my_dLi_dS, S, ph, me) + call damage_isoductile_LiAndItsTangent(my_Li, my_dLi_dS, S, ph, me) Li = Li + my_Li dLi_dS = dLi_dS + my_dLi_dS active = .true. diff --git a/src/phase_mechanical_eigen_cleavageopening.f90 b/src/phase_mechanical_eigen_cleavageopening.f90 index bccf1cb5f..4243d09a4 100644 --- a/src/phase_mechanical_eigen_cleavageopening.f90 +++ b/src/phase_mechanical_eigen_cleavageopening.f90 @@ -13,7 +13,7 @@ contains !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module function kinematics_cleavage_opening_init() result(myKinematics) +module function damage_anisobrittle_init() result(myKinematics) logical, dimension(:), allocatable :: myKinematics @@ -24,7 +24,7 @@ module function kinematics_cleavage_opening_init() result(myKinematics) print'(/,a)', ' <<<+- phase:mechanical:eigen:cleavageopening init -+>>>' print'(a,i2)', ' # phases: ',count(myKinematics); flush(IO_STDOUT) -end function kinematics_cleavage_opening_init +end function damage_anisobrittle_init end submodule cleavageopening diff --git a/src/phase_mechanical_eigen_slipplaneopening.f90 b/src/phase_mechanical_eigen_slipplaneopening.f90 index 18d99f750..2fd14700d 100644 --- a/src/phase_mechanical_eigen_slipplaneopening.f90 +++ b/src/phase_mechanical_eigen_slipplaneopening.f90 @@ -6,7 +6,7 @@ !-------------------------------------------------------------------------------------------------- submodule(phase:eigen) slipplaneopening - integer, dimension(:), allocatable :: kinematics_slipplane_opening_instance + integer, dimension(:), allocatable :: damage_isoductile_instance type :: tParameters !< container type for internal constitutive parameters integer :: & @@ -32,7 +32,7 @@ contains !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module function kinematics_slipplane_opening_init() result(myKinematics) +module function damage_isoductile_init() result(myKinematics) logical, dimension(:), allocatable :: myKinematics @@ -107,13 +107,13 @@ module function kinematics_slipplane_opening_init() result(myKinematics) enddo -end function kinematics_slipplane_opening_init +end function damage_isoductile_init !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the velocity gradient !-------------------------------------------------------------------------------------------------- -module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ph,me) +module subroutine damage_isoductile_LiAndItsTangent(Ld, dLd_dTstar, S, ph,me) integer, intent(in) :: & ph, me @@ -179,6 +179,6 @@ module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S end associate -end subroutine kinematics_slipplane_opening_LiAndItsTangent +end subroutine damage_isoductile_LiAndItsTangent end submodule slipplaneopening From 6bc1d5ad98ea6d3702c16632547ffc827e5e2774 Mon Sep 17 00:00:00 2001 From: Test User Date: Tue, 6 Apr 2021 13:02:23 +0200 Subject: [PATCH 128/219] [skip ci] updated version information after successful test of v3.0.0-alpha2-756-g39f4efa55 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index e5c6789ca..149e4ab91 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-753-g565dab120 +v3.0.0-alpha2-756-g39f4efa55 From 5a361c12f8b36e76383c911bce42be71297748e7 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 6 Apr 2021 15:53:06 +0200 Subject: [PATCH 129/219] bugfix: corrected name --- src/homogenization_thermal.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index 00cb438d1..7bb81d24a 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -10,8 +10,8 @@ submodule(homogenization) thermal module subroutine pass_init end subroutine pass_init - module subroutine isothermal_init - end subroutine isothermal_init + module subroutine isotemperature_init + end subroutine isotemperature_init end interface From bf4c88a39ef228c99026e9cfaf4064f5ad09d8df Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Tue, 6 Apr 2021 11:39:44 -0400 Subject: [PATCH 130/219] renamed result.read to get; polishing --- PRIVATE | 2 +- python/damask/_result.py | 220 ++++++++++++++++++------------------ python/tests/test_Result.py | 34 +++--- 3 files changed, 129 insertions(+), 127 deletions(-) diff --git a/PRIVATE b/PRIVATE index 90ad4d1c4..129812414 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 90ad4d1c4e7ef9ccd8e6b30ee9b771dd6187f372 +Subproject commit 1298124143e7e2901d0b9c2e79ab6388cb78a1e3 diff --git a/python/damask/_result.py b/python/damask/_result.py index dcb192cf9..4856a17fa 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -49,7 +49,7 @@ def _match(requested,existing): return sorted(set(flatten_list([fnmatch.filter(existing,r) for r in requested_])), key=util.natural_sort) -def _empty(dataset,N_materialpoints,fill_float,fill_int): +def _empty_like(dataset,N_materialpoints,fill_float,fill_int): """Create empty numpy.ma.MaskedArray.""" return ma.array(np.empty((N_materialpoints,)+dataset.shape[1:],dataset.dtype), fill_value = fill_float if dataset.dtype in np.sctypes['float'] else fill_int, @@ -95,8 +95,8 @@ class Result: r=re.compile('inc[0-9]+' if self.version_minor < 12 else 'increment_[0-9]+') self.increments = sorted([i for i in f.keys() if r.match(i)],key=util.natural_sort) - self.times = [round(f[i].attrs['time/s'],12) for i in self.increments] if self.version_minor < 12 else \ - [round(f[i].attrs['t/s'],12) for i in self.increments] + self.times = [round(f[i].attrs['time/s' if self.version_minor < 12 else + 't/s'],12) for i in self.increments] grp = 'mapping' if self.version_minor < 12 else 'cell_to' @@ -159,9 +159,9 @@ class Result: Select from 'set', 'add', and 'del'. what : str Attribute to change (must be from self.visible). - datasets : str, int, list of str, list of int, or bool - Name of datasets as list; supports ? and * wildcards. - True is equivalent to [*], False is equivalent to []. + datasets : (list of) int (for increments), (list of) float (for times), (list of) str, or bool + Name of datasets; supports '?' and '*' wildcards. + True is equivalent to '*', False is equivalent to []. """ # allow True/False and string arguments @@ -270,9 +270,9 @@ class Result: ---------- what : {'increments', 'times', 'phases', 'homogenizations', 'fields'} Attribute to change. - datasets : int (for increments), float (for times), str or list of, bool - Name of datasets as list; supports ? and * wildcards. - True is equivalent to *, False is equivalent to []. + datasets : (list of) int (for increments), (list of) float (for times), (list of) str, or bool + Name of datasets; supports '?' and '*' wildcards. + True is equivalent to '*', False is equivalent to []. """ return self._manage_view('set',what,datasets) @@ -286,9 +286,9 @@ class Result: ---------- what : {'increments', 'times', 'phases', 'homogenizations', 'fields'} Attribute to change. - datasets : int (for increments), float (for times), str or list of, bool - Name of datasets as list; supports ? and * wildcards. - True is equivalent to *, False is equivalent to []. + datasets : (list of) int (for increments), (list of) float (for times), (list of) str, or bool + Name of datasets; supports '?' and '*' wildcards. + True is equivalent to '*', False is equivalent to []. """ return self._manage_view('add',what,datasets) @@ -302,9 +302,9 @@ class Result: ---------- what : {'increments', 'times', 'phases', 'homogenizations', 'fields'} Attribute to change. - datasets : int (for increments), float (for times), str or list of, bool - Name of datasets as list; supports ? and * wildcards. - True is equivalent to *, False is equivalent to []. + datasets : (list of) int (for increments), (list of) float (for times), (list of) str, or bool + Name of datasets; supports '?' and '*' wildcards. + True is equivalent to '*', False is equivalent to []. """ return self._manage_view('del',what,datasets) @@ -448,7 +448,7 @@ class Result: label : str Label of resulting dataset. formula : str - Formula to calculate resulting dataset. Existing datasets are referenced by ‘#TheirLabel#‘. + Formula to calculate resulting dataset. Existing datasets are referenced by '#TheirLabel#'. unit : str, optional Physical unit of the result. description : str, optional @@ -480,9 +480,9 @@ class Result: Parameters ---------- P : str, optional - Label of the dataset containing the first Piola-Kirchhoff stress. Defaults to ‘P’. + Label of the dataset containing the first Piola-Kirchhoff stress. Defaults to 'P'. F : str, optional - Label of the dataset containing the deformation gradient. Defaults to ‘F’. + Label of the dataset containing the deformation gradient. Defaults to 'F'. """ self._add_generic_pointwise(self._add_stress_Cauchy,{'P':P,'F':F}) @@ -563,7 +563,7 @@ class Result: T_sym : str Label of symmetric tensor dataset. eigenvalue : str, optional - Eigenvalue. Select from ‘max’, ‘mid’, ‘min’. Defaults to ‘max’. + Eigenvalue. Select from 'max', 'mid', 'min'. Defaults to 'max'. """ self._add_generic_pointwise(self._add_eigenvalue,{'T_sym':T_sym},{'eigenvalue':eigenvalue}) @@ -596,8 +596,8 @@ class Result: T_sym : str Label of symmetric tensor dataset. eigenvalue : str, optional - Eigenvalue to which the eigenvector corresponds. Select from - ‘max’, ‘mid’, ‘min’. Defaults to ‘max’. + Eigenvalue to which the eigenvector corresponds. + Select from 'max', 'mid', 'min'. Defaults to 'max'. """ self._add_generic_pointwise(self._add_eigenvector,{'T_sym':T_sym},{'eigenvalue':eigenvalue}) @@ -696,7 +696,7 @@ class Result: Label of symmetric tensorial stress or strain dataset. kind : {'stress', 'strain', None}, optional Kind of the von Mises equivalent. Defaults to None, in which case - it is selected based on the unit of the dataset ('1' -> strain, 'Pa' -> stress'). + it is selected based on the unit of the dataset ('1' -> strain, 'Pa' -> stress). """ self._add_generic_pointwise(self._add_equivalent_Mises,{'T_sym':T_sym},{'kind':kind}) @@ -733,7 +733,7 @@ class Result: ---------- x : str Label of vector or tensor dataset. - ord : {non-zero int, inf, -inf, ‘fro’, ‘nuc’}, optional + ord : {non-zero int, inf, -inf, 'fro', 'nuc'}, optional Order of the norm. inf means NumPy’s inf object. For details refer to numpy.linalg.norm. """ @@ -760,9 +760,9 @@ class Result: Parameters ---------- P : str, optional - Label of first Piola-Kirchhoff stress dataset. Defaults to ‘P’. + Label of first Piola-Kirchhoff stress dataset. Defaults to 'P'. F : str, optional - Label of deformation gradient dataset. Defaults to ‘F’. + Label of deformation gradient dataset. Defaults to 'F'. """ self._add_generic_pointwise(self._add_stress_second_Piola_Kirchhoff,{'P':P,'F':F}) @@ -874,17 +874,17 @@ class Result: """ Add strain tensor of a deformation gradient. - For details refer to damask.mechanics.strain + For details, see damask.mechanics.strain. Parameters ---------- F : str, optional - Label of deformation gradient dataset. Defaults to ‘F’. - t : {‘V’, ‘U’}, optional - Type of the polar decomposition, ‘V’ for left stretch tensor and ‘U’ for right stretch tensor. - Defaults to ‘V’. + Label of deformation gradient dataset. Defaults to 'F'. + t : {'V', 'U'}, optional + Type of the polar decomposition, 'V' for left stretch tensor and 'U' for right stretch tensor. + Defaults to 'V'. m : float, optional - Order of the strain calculation. Defaults to ‘0.0’. + Order of the strain calculation. Defaults to 0.0. """ self._add_generic_pointwise(self._add_strain,{'F':F},{'t':t,'m':m}) @@ -909,10 +909,10 @@ class Result: Parameters ---------- F : str, optional - Label of deformation gradient dataset. Defaults to ‘F’. - t : {‘V’, ‘U’}, optional - Type of the polar decomposition, ‘V’ for left stretch tensor and ‘U’ for right stretch tensor. - Defaults to ‘V’. + Label of deformation gradient dataset. Defaults to 'F'. + t : {'V', 'U'}, optional + Type of the polar decomposition, 'V' for left stretch tensor and 'U' for right stretch tensor. + Defaults to 'V'. """ self._add_generic_pointwise(self._add_stretch_tensor,{'F':F},{'t':t}) @@ -947,8 +947,8 @@ class Result: Callback function that calculates a new dataset from one or more datasets per HDF5 group. datasets : dictionary - Details of the datasets to be used: label (in HDF5 file) and - arg (argument to which the data is parsed in func). + Details of the datasets to be used: + {arg (name to which the data is passed in func): label (in HDF5 file)}. args : dictionary, optional Arguments parsed to func. @@ -1018,14 +1018,14 @@ class Result: Parameters ---------- - output : str or list of str - Labels of the datasets to read. Defaults to '*', in which - case all datasets are considered. + output : (list of) str + Labels of the datasets to read. + Defaults to '*', in which case all datasets are considered. """ u = 'Unit' if self.version_minor < 12 else 'unit' # compatibility hack if self.N_constituents != 1 or len(self.phases) != 1 or not self.structured: - raise TypeError('XDMF output requires homogeneous grid') + raise TypeError('XDMF output requires structured grid with single phase and single constituent.') attribute_type_map = defaultdict(lambda:'Matrix', ( ((),'Scalar'), ((3,),'Vector'), ((3,3),'Tensor')) ) @@ -1036,11 +1036,11 @@ class Result: if dtype in np.sctypes['float']: return 'Float' - xdmf=ET.Element('Xdmf') + xdmf = ET.Element('Xdmf') xdmf.attrib={'Version': '2.0', 'xmlns:xi': 'http://www.w3.org/2001/XInclude'} - domain=ET.SubElement(xdmf, 'Domain') + domain = ET.SubElement(xdmf, 'Domain') collection = ET.SubElement(domain, 'Grid') collection.attrib={'GridType': 'Collection', @@ -1062,38 +1062,38 @@ class Result: with h5py.File(self.fname,'r') as f: for inc in self.visible['increments']: - grid=ET.SubElement(collection,'Grid') + grid = ET.SubElement(collection,'Grid') grid.attrib = {'GridType': 'Uniform', 'Name': inc} - topology=ET.SubElement(grid, 'Topology') - topology.attrib={'TopologyType': '3DCoRectMesh', - 'Dimensions': '{} {} {}'.format(*self.cells+1)} + topology = ET.SubElement(grid, 'Topology') + topology.attrib = {'TopologyType': '3DCoRectMesh', + 'Dimensions': '{} {} {}'.format(*(self.cells+1))} - geometry=ET.SubElement(grid, 'Geometry') - geometry.attrib={'GeometryType':'Origin_DxDyDz'} + geometry = ET.SubElement(grid, 'Geometry') + geometry.attrib = {'GeometryType':'Origin_DxDyDz'} - origin=ET.SubElement(geometry, 'DataItem') - origin.attrib={'Format': 'XML', - 'NumberType': 'Float', - 'Dimensions': '3'} - origin.text="{} {} {}".format(*self.origin) + origin = ET.SubElement(geometry, 'DataItem') + origin.attrib = {'Format': 'XML', + 'NumberType': 'Float', + 'Dimensions': '3'} + origin.text = "{} {} {}".format(*self.origin) - delta=ET.SubElement(geometry, 'DataItem') - delta.attrib={'Format': 'XML', - 'NumberType': 'Float', - 'Dimensions': '3'} + delta = ET.SubElement(geometry, 'DataItem') + delta.attrib = {'Format': 'XML', + 'NumberType': 'Float', + 'Dimensions': '3'} delta.text="{} {} {}".format(*(self.size/self.cells)) attributes.append(ET.SubElement(grid, 'Attribute')) - attributes[-1].attrib={'Name': 'u / m', - 'Center': 'Node', - 'AttributeType': 'Vector'} + attributes[-1].attrib = {'Name': 'u / m', + 'Center': 'Node', + 'AttributeType': 'Vector'} data_items.append(ET.SubElement(attributes[-1], 'DataItem')) - data_items[-1].attrib={'Format': 'HDF', - 'Precision': '8', - 'Dimensions': '{} {} {} 3'.format(*(self.cells+1))} - data_items[-1].text=f'{os.path.split(self.fname)[1]}:/{inc}/geometry/u_n' + data_items[-1].attrib = {'Format': 'HDF', + 'Precision': '8', + 'Dimensions': '{} {} {} 3'.format(*(self.cells+1))} + data_items[-1].text = f'{os.path.split(self.fname)[1]}:/{inc}/geometry/u_n' for ty in ['phase','homogenization']: for label in self.visible[ty+'s']: @@ -1106,25 +1106,25 @@ class Result: unit = f[name].attrs[u] if h5py3 else f[name].attrs[u].decode() attributes.append(ET.SubElement(grid, 'Attribute')) - attributes[-1].attrib={'Name': name.split('/',2)[2]+f' / {unit}', - 'Center': 'Cell', - 'AttributeType': attribute_type_map[shape]} + attributes[-1].attrib = {'Name': name.split('/',2)[2]+f' / {unit}', + 'Center': 'Cell', + 'AttributeType': attribute_type_map[shape]} data_items.append(ET.SubElement(attributes[-1], 'DataItem')) - data_items[-1].attrib={'Format': 'HDF', - 'NumberType': number_type_map(dtype), - 'Precision': f'{dtype.itemsize}', - 'Dimensions': '{} {} {} {}'.format(*self.cells,1 if shape == () else - np.prod(shape))} - data_items[-1].text=f'{os.path.split(self.fname)[1]}:{name}' + data_items[-1].attrib = {'Format': 'HDF', + 'NumberType': number_type_map(dtype), + 'Precision': f'{dtype.itemsize}', + 'Dimensions': '{} {} {} {}'.format(*self.cells,1 if shape == () else + np.prod(shape))} + data_items[-1].text = f'{os.path.split(self.fname)[1]}:{name}' with open(self.fname.with_suffix('.xdmf').name,'w',newline='\n') as f: f.write(xml.dom.minidom.parseString(ET.tostring(xdmf).decode()).toprettyxml()) def _mappings(self): - grp = 'mapping' if self.version_minor < 12 else 'cell_to' # compatibility hack - name = 'Name' if self.version_minor < 12 else 'label' # compatibility hack - member = 'member' if self.version_minor < 12 else 'entry' # compatibility hack + grp = 'mapping' if self.version_minor < 12 else 'cell_to' # compatibility hack + name = 'Name' if self.version_minor < 12 else 'label' # compatibility hack + member = 'member' if self.version_minor < 12 else 'entry' # compatibility hack with h5py.File(self.fname,'r') as f: @@ -1146,22 +1146,22 @@ class Result: def save_VTK(self,output='*',mode='cell',constituents=None,fill_float=np.nan,fill_int=0,parallel=True): """ - Export to vtk cell/point data. + Export to VTK cell/point data. Parameters ---------- - output : str or list of, optional - Labels of the datasets to place. Defaults to '*', in which - case all datasets are exported. - mode : str, either 'cell' or 'point' + output : (list of) str, optional + Labels of the datasets to place. + Defaults to '*', in which case all datasets are exported. + mode : {'cell', 'point'} Export in cell format or point format. Defaults to 'cell'. - constituents : int or list of, optional - Constituents to consider. Defaults to 'None', in which case - all constituents are considered. + constituents : (list of) int, optional + Constituents to consider. + Defaults to None, in which case all constituents are considered. fill_float : float Fill value for non-existent entries of floating point type. - Defaults to 0.0. + Defaults to NaN. fill_int : int Fill value for non-existent entries of integer type. Defaults to 0. @@ -1206,14 +1206,14 @@ class Result: if out+suffixes[0] not in outs.keys(): for c,suffix in zip(constituents_,suffixes): outs[out+suffix] = \ - _empty(data,self.N_materialpoints,fill_float,fill_int) + _empty_like(data,self.N_materialpoints,fill_float,fill_int) for c,suffix in zip(constituents_,suffixes): outs[out+suffix][at_cell_ph[c][label]] = data[in_data_ph[c][label]] if ty == 'homogenization': if out not in outs.keys(): - outs[out] = _empty(data,self.N_materialpoints,fill_float,fill_int) + outs[out] = _empty_like(data,self.N_materialpoints,fill_float,fill_int) outs[out][at_cell_ho[label]] = data[in_data_ho[label]] @@ -1223,18 +1223,15 @@ class Result: v.save(f'{self.fname.stem}_inc{inc[ln:].zfill(N_digits)}',parallel=parallel) - def read(self,output='*',flatten=True,prune=True): + def get(self,output='*',flatten=True,prune=True): """ - Export data per phase/homogenization. - - The returned data structure reflects the group/folder structure - in the DADF5 file. + Collect data per phase/homogenization reflecting the group/folder structure in the DADF5 file. Parameters ---------- - output : str or list of str - Labels of the datasets to read. Defaults to '*', in which - case all datasets are read. + output : (list of) str + Labels of the datasets to read. + Defaults to '*', in which case all datasets are read. flatten : bool Remove singular levels of the folder hierarchy. This might be beneficial in case of single increment, @@ -1242,6 +1239,11 @@ class Result: prune : bool Remove branches with no data. Defaults to True. + Returns + ------- + data : dict of numpy.ndarray + Datasets structured by phase/homogenization and according to selected view. + """ r = {} @@ -1266,9 +1268,9 @@ class Result: return r - def place(self,output='*',flatten=True,prune=True,constituents=None,fill_float=0.0,fill_int=0): + def place(self,output='*',flatten=True,prune=True,constituents=None,fill_float=np.nan,fill_int=0): """ - Export data in spatial order that is compatible with the damask.VTK geometry representation. + Merge data into spatial order that is compatible with the damask.VTK geometry representation. The returned data structure reflects the group/folder structure in the DADF5 file. @@ -1279,21 +1281,21 @@ class Result: Parameters ---------- - output : str or list of, optional - Labels of the datasets to place. Defaults to '*', in which - case all datasets are placed. + output : (list of) str, optional + Labels of the datasets to place. + Defaults to '*', in which case all datasets are placed. flatten : bool Remove singular levels of the folder hierarchy. - This might be beneficial in case of single increment - or field. Defaults to True. + This might be beneficial in case of single increment or field. + Defaults to True. prune : bool Remove branches with no data. Defaults to True. - constituents : int or list of, optional - Constituents to consider. Defaults to 'None', in which case - all constituents are considered. + constituents : (list of) int, optional + Constituents to consider. + Defaults to 'None', in which case all constituents are considered. fill_float : float Fill value for non-existent entries of floating point type. - Defaults to 0.0. + Defaults to NaN. fill_int : int Fill value for non-existent entries of integer type. Defaults to 0. @@ -1330,7 +1332,7 @@ class Result: if out+suffixes[0] not in r[inc][ty][field].keys(): for c,suffix in zip(constituents_,suffixes): r[inc][ty][field][out+suffix] = \ - _empty(data,self.N_materialpoints,fill_float,fill_int) + _empty_like(data,self.N_materialpoints,fill_float,fill_int) for c,suffix in zip(constituents_,suffixes): r[inc][ty][field][out+suffix][at_cell_ph[c][label]] = data[in_data_ph[c][label]] @@ -1338,7 +1340,7 @@ class Result: if ty == 'homogenization': if out not in r[inc][ty][field].keys(): r[inc][ty][field][out] = \ - _empty(data,self.N_materialpoints,fill_float,fill_int) + _empty_like(data,self.N_materialpoints,fill_float,fill_int) r[inc][ty][field][out][at_cell_ho[label]] = data[in_data_ho[label]] diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 766046369..f9112e34f 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -56,19 +56,19 @@ class TestResult: def test_view_all(self,default): - a = default.view('increments',True).read('F') + a = default.view('increments',True).get('F') - assert dict_equal(a,default.view('increments','*').read('F')) - assert dict_equal(a,default.view('increments',default.increments_in_range(0,np.iinfo(int).max)).read('F')) + assert dict_equal(a,default.view('increments','*').get('F')) + assert dict_equal(a,default.view('increments',default.increments_in_range(0,np.iinfo(int).max)).get('F')) - assert dict_equal(a,default.view('times',True).read('F')) - assert dict_equal(a,default.view('times','*').read('F')) - assert dict_equal(a,default.view('times',default.times_in_range(0.0,np.inf)).read('F')) + assert dict_equal(a,default.view('times',True).get('F')) + assert dict_equal(a,default.view('times','*').get('F')) + assert dict_equal(a,default.view('times',default.times_in_range(0.0,np.inf)).get('F')) @pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations def test_view_none(self,default,what): - a = default.view(what,False).read('F') - b = default.view(what,[]).read('F') + a = default.view(what,False).get('F') + b = default.view(what,[]).get('F') assert a == b == {} @@ -76,8 +76,8 @@ class TestResult: def test_view_more(self,default,what): empty = default.view(what,False) - a = empty.view_more(what,'*').read('F') - b = empty.view_more(what,True).read('F') + a = empty.view_more(what,'*').get('F') + b = empty.view_more(what,True).get('F') assert dict_equal(a,b) @@ -85,8 +85,8 @@ class TestResult: def test_view_less(self,default,what): full = default.view(what,True) - a = full.view_less(what,'*').read('F') - b = full.view_less(what,True).read('F') + a = full.view_less(what,'*').get('F') + b = full.view_less(what,True).get('F') assert a == b == {} @@ -189,7 +189,7 @@ class TestResult: default.add_stress_Cauchy('P','F') default.add_calculation('sigma_y','#sigma#',unit='y') default.add_equivalent_Mises('sigma_y') - assert default.read('sigma_y_vM') == {} + assert default.get('sigma_y_vM') == {} def test_add_Mises_stress_strain(self,default): default.add_stress_Cauchy('P','F') @@ -326,7 +326,7 @@ class TestResult: for i in range(10): if os.path.isfile(tmp_path/fname): with open(fname) as f: - cur = hashlib.md5(f.read().encode()).hexdigest() + cur = hashlib.md5(f.get().encode()).hexdigest() if cur == last: break else: @@ -336,7 +336,7 @@ class TestResult: with open((ref_path/'save_VTK'/request.node.name).with_suffix('.md5'),'w') as f: f.write(cur) with open((ref_path/'save_VTK'/request.node.name).with_suffix('.md5')) as f: - assert cur == f.read() + assert cur == f.get() @pytest.mark.parametrize('mode',['point','cell']) def test_vtk_mode(self,tmp_path,single_phase,mode): @@ -352,7 +352,7 @@ class TestResult: single_phase.save_XDMF() if update: shutil.copy(tmp_path/fname,ref_path/fname) - assert sorted(open(tmp_path/fname).read()) == sorted(open(ref_path/fname).read()) # XML is not ordered + assert sorted(open(tmp_path/fname).get()) == sorted(open(ref_path/fname).get()) # XML is not ordered def test_XDMF_invalid(self,default): with pytest.raises(TypeError): @@ -374,7 +374,7 @@ class TestResult: result = result.view(key,value) fname = request.node.name - cur = result.read(output,compress,strip) + cur = result.get(output,compress,strip) if update: with bz2.BZ2File((ref_path/'read'/fname).with_suffix('.pbz2'),'w') as f: pickle.dump(cur,f) From bf2515c4c16b1c559e71cf4b66d99a3c75d94952 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Tue, 6 Apr 2021 12:10:35 -0400 Subject: [PATCH 131/219] removed `Grid.diff` in lieu of `__eq__` --- python/damask/_grid.py | 38 +++++++------------------------------ python/tests/test_Grid.py | 8 ++------ python/tests/test_Result.py | 6 +++--- 3 files changed, 12 insertions(+), 40 deletions(-) diff --git a/python/damask/_grid.py b/python/damask/_grid.py index 5457643ee..308be5c80 100644 --- a/python/damask/_grid.py +++ b/python/damask/_grid.py @@ -69,9 +69,9 @@ class Grid: copy = __copy__ - def diff(self,other): + def __eq__(self,other): """ - Report property differences of self relative to other. + Test equality of other. Parameters ---------- @@ -79,34 +79,10 @@ class Grid: Grid to compare self against. """ - message = [] - if np.any(other.cells != self.cells): - message.append(util.deemph(f'cells x y z: {util.srepr(other.cells," x ")}')) - message.append(util.emph( f'cells x y z: {util.srepr( self.cells," x ")}')) - - if not np.allclose(other.size,self.size): - message.append(util.deemph(f'size x y z: {util.srepr(other.size," x ")}')) - message.append(util.emph( f'size x y z: {util.srepr( self.size," x ")}')) - - if not np.allclose(other.origin,self.origin): - message.append(util.deemph(f'origin x y z: {util.srepr(other.origin," ")}')) - message.append(util.emph( f'origin x y z: {util.srepr( self.origin," ")}')) - - if other.N_materials != self.N_materials: - message.append(util.deemph(f'# materials: {other.N_materials}')) - message.append(util.emph( f'# materials: { self.N_materials}')) - - if np.nanmin(other.material) != np.nanmin(self.material): - message.append(util.deemph(f'min material: {np.nanmin(other.material)}')) - message.append(util.emph( f'min material: {np.nanmin( self.material)}')) - - if np.nanmax(other.material) != np.nanmax(self.material): - message.append(util.deemph(f'max material: {np.nanmax(other.material)}')) - message.append(util.emph( f'max material: {np.nanmax( self.material)}')) - - print(util.srepr(message)) - - return True if message != [] or (other.material != self.material).any() else False + return (np.allclose(other.size,self.size) + and np.allclose(other.origin,self.origin) + and np.all(other.cells == self.cells) + and np.all(other.material == self.material)) @property @@ -276,7 +252,7 @@ class Grid: """ Load DREAM.3D (HDF5) file. - Data in DREAM.3D files can be stored per cell ('CellData') and/or + Data in DREAM.3D files can be stored per cell ('CellData') and/or per grain ('Grain Data'). Per default, cell-wise data is assumed. damask.ConfigMaterial.load_DREAM3D gives the corresponding material definition. diff --git a/python/tests/test_Grid.py b/python/tests/test_Grid.py index 6ccd100fc..9d82bde78 100644 --- a/python/tests/test_Grid.py +++ b/python/tests/test_Grid.py @@ -41,13 +41,9 @@ class TestGrid: def _patch_datetime_now(self, patch_datetime_now): print('patched datetime.datetime.now') - def test_diff_equal(self,default): - assert not default.diff(default) - - def test_diff_not_equal(self,default): - new = Grid(default.material[1:,1:,1:]+1,default.size*.9,np.ones(3)-default.origin,comments=['modified']) - assert default.diff(new) + def test_equal(self,default): + assert default == default def test_repr(self,default): print(default) diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index f9112e34f..63852efc5 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -326,7 +326,7 @@ class TestResult: for i in range(10): if os.path.isfile(tmp_path/fname): with open(fname) as f: - cur = hashlib.md5(f.get().encode()).hexdigest() + cur = hashlib.md5(f.read().encode()).hexdigest() if cur == last: break else: @@ -336,7 +336,7 @@ class TestResult: with open((ref_path/'save_VTK'/request.node.name).with_suffix('.md5'),'w') as f: f.write(cur) with open((ref_path/'save_VTK'/request.node.name).with_suffix('.md5')) as f: - assert cur == f.get() + assert cur == f.read() @pytest.mark.parametrize('mode',['point','cell']) def test_vtk_mode(self,tmp_path,single_phase,mode): @@ -352,7 +352,7 @@ class TestResult: single_phase.save_XDMF() if update: shutil.copy(tmp_path/fname,ref_path/fname) - assert sorted(open(tmp_path/fname).get()) == sorted(open(ref_path/fname).get()) # XML is not ordered + assert sorted(open(tmp_path/fname).read()) == sorted(open(ref_path/fname).read()) # XML is not ordered def test_XDMF_invalid(self,default): with pytest.raises(TypeError): From bc1454970cf601eb423a865acfc648d0a875993a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 6 Apr 2021 22:49:08 +0200 Subject: [PATCH 132/219] mandatory symmetry if symmetry is not of interest, damask.Rotation should be used --- python/damask/_orientation.py | 45 +++++++------------------------- python/tests/test_Config.py | 4 +-- python/tests/test_Orientation.py | 40 ++++++++-------------------- 3 files changed, 22 insertions(+), 67 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 0a48279af..5875f1d1c 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -86,11 +86,11 @@ class Orientation(Rotation): """ crystal_families = ['triclinic', - 'monoclinic', - 'orthorhombic', - 'tetragonal', - 'hexagonal', - 'cubic'] + 'monoclinic', + 'orthorhombic', + 'tetragonal', + 'hexagonal', + 'cubic'] lattice_symmetries = { 'aP': 'triclinic', @@ -136,8 +136,7 @@ class Orientation(Rotation): Rotation.__init__(self) if rotation is None else Rotation.__init__(self,rotation=rotation) - if ( lattice is not None - and lattice not in self.lattice_symmetries + if ( lattice not in self.lattice_symmetries and lattice not in self.crystal_families): raise KeyError(f'Lattice "{lattice}" is unknown') @@ -206,7 +205,7 @@ class Orientation(Rotation): def __repr__(self): """Represent.""" return '\n'.join(([] if self.lattice is None else [f'Bravais lattice {self.lattice}']) - + ([] if self.family is None else [f'Crystal family {self.family}']) + + ([f'Crystal family {self.family}']) + [super().__repr__()]) @@ -239,9 +238,7 @@ class Orientation(Rotation): """ matching_type = all([hasattr(other,attr) and getattr(self,attr) == getattr(other,attr) for attr in ['family','lattice','parameters']]) - s = self if self.family is None else self.reduced - o = other if other.family is None else other.reduced - return np.logical_and(super(__class__,s).__eq__(o),matching_type) + return np.logical_and(super(__class__,self.reduced).__eq__(other.reduced),matching_type) def __ne__(self,other): """ @@ -279,9 +276,7 @@ class Orientation(Rotation): """ matching_type = all([hasattr(other,attr) and getattr(self,attr) == getattr(other,attr) for attr in ['family','lattice','parameters']]) - s = self if self.family is None else self.reduced - o = other if other.family is None else other.reduced - return np.logical_and(super(__class__,s).isclose(o),matching_type) + return np.logical_and(super(__class__,self.reduced).isclose(other.reduced),matching_type) @@ -546,9 +541,6 @@ class Orientation(Rotation): is added to the left of the Rotation array. """ - if self.family is None: - raise ValueError('Missing crystal symmetry') - o = self.symmetry_operations.broadcast_to(self.symmetry_operations.shape+self.shape,mode='right') return self.copy(rotation=o*Rotation(self.quaternion).broadcast_to(o.shape,mode='left')) @@ -556,9 +548,6 @@ class Orientation(Rotation): @property def reduced(self): """Select symmetrically equivalent orientation that falls into fundamental zone according to symmetry.""" - if self.family is None: - raise ValueError('Missing crystal symmetry') - eq = self.equivalent ok = eq.in_FZ ok &= np.cumsum(ok,axis=0) == 1 @@ -587,9 +576,6 @@ class Orientation(Rotation): https://doi.org/10.1107/S0108767391006864 """ - if self.family is None: - raise ValueError('Missing crystal symmetry') - rho_abs = np.abs(self.as_Rodrigues_vector(compact=True))*(1.-1.e-9) with np.errstate(invalid='ignore'): @@ -630,9 +616,6 @@ class Orientation(Rotation): https://doi.org/10.1107/S0108767391006864 """ - if self.family is None: - raise ValueError('Missing crystal symmetry') - rho = self.as_Rodrigues_vector(compact=True)*(1.0-1.0e-9) with np.errstate(invalid='ignore'): @@ -783,8 +766,6 @@ class Orientation(Rotation): 'beta': np.pi/2., 'gamma': np.pi/2., } - else: - raise KeyError(f'Crystal family "{self.family}" is unknown') @property @@ -1081,8 +1062,6 @@ class Orientation(Rotation): Bunge Eulers / deg: (11.40, 21.86, 0.60) """ - if self.family is None or other.family is None: - raise ValueError('missing crystal symmetry') if self.family != other.family: raise NotImplementedError('disorientation between different crystal families') @@ -1139,9 +1118,6 @@ class Orientation(Rotation): https://doi.org/10.1107/S0021889801003077 """ - if self.family is None: - raise ValueError('Missing crystal symmetry') - eq = self.equivalent m = eq.misorientation(self[...,0].reshape((1,)+self.shape[:-1]+(1,)) .broadcast_to(eq.shape))\ @@ -1183,9 +1159,6 @@ class Orientation(Rotation): Index of symmetrically equivalent orientation that rotated vector to SST. """ - if self.family is None: - raise ValueError('Missing crystal symmetry') - eq = self.equivalent blend = util.shapeblender(eq.shape,np.array(vector).shape[:-1]) poles = eq.broadcast_to(blend,mode='right') @ np.broadcast_to(np.array(vector),blend+(3,)) diff --git a/python/tests/test_Config.py b/python/tests/test_Config.py index c64573d93..d2f0b5e72 100644 --- a/python/tests/test_Config.py +++ b/python/tests/test_Config.py @@ -53,7 +53,7 @@ class TestConfig: def test_abstract_is_complete(self): assert Config().is_complete is None - - @pytest.mark.parametrize('data',[Rotation.from_random(),Orientation.from_random()]) + + @pytest.mark.parametrize('data',[Rotation.from_random(),Orientation.from_random(lattice='cI')]) def test_rotation_orientation(self,data): assert str(Config(a=data)) == str(Config(a=data.as_quaternion())) diff --git a/python/tests/test_Orientation.py b/python/tests/test_Orientation.py index 6f3503b73..dce0cf40f 100644 --- a/python/tests/test_Orientation.py +++ b/python/tests/test_Orientation.py @@ -37,9 +37,15 @@ class TestOrientation: assert not ( Orientation(R,lattice) != Orientation(R,lattice) if shape is None else \ (Orientation(R,lattice) != Orientation(R,lattice)).any()) + @pytest.mark.parametrize('lattice',Orientation.crystal_families) + @pytest.mark.parametrize('shape',[None,5,(4,6)]) + def test_close(self,lattice,shape): + R = Orientation.from_random(lattice=lattice,shape=shape) + assert R.isclose(R.reduced).all() and R.allclose(R.reduced) + @pytest.mark.parametrize('a,b',[ - (dict(rotation=[1,0,0,0]), - dict(rotation=[0.5,0.5,0.5,0.5])), + (dict(rotation=[1,0,0,0],lattice='triclinic'), + dict(rotation=[0.5,0.5,0.5,0.5],lattice='triclinic')), (dict(rotation=[1,0,0,0],lattice='cubic'), dict(rotation=[1,0,0,0],lattice='hexagonal')), @@ -335,33 +341,9 @@ class TestOrientation: o.family = invalid_family o.symmetry_operations # noqa - def test_missing_symmetry_equivalent(self): - with pytest.raises(ValueError): - Orientation(lattice=None).equivalent # noqa - - def test_missing_symmetry_reduced(self): - with pytest.raises(ValueError): - Orientation(lattice=None).reduced # noqa - - def test_missing_symmetry_in_FZ(self): - with pytest.raises(ValueError): - Orientation(lattice=None).in_FZ # noqa - - def test_missing_symmetry_in_disorientation_FZ(self): - with pytest.raises(ValueError): - Orientation(lattice=None).in_disorientation_FZ # noqa - - def test_missing_symmetry_disorientation(self): - with pytest.raises(ValueError): - Orientation(lattice=None).disorientation(Orientation(lattice=None)) # noqa - - def test_missing_symmetry_average(self): - with pytest.raises(ValueError): - Orientation(lattice=None).average() # noqa - - def test_missing_symmetry_to_SST(self): - with pytest.raises(ValueError): - Orientation(lattice=None).to_SST(np.zeros(3)) # noqa + def test_invalid_rot(self): + with pytest.raises(TypeError): + Orientation.from_random(lattice='cubic') * np.ones(3) def test_missing_symmetry_immutable(self): with pytest.raises(KeyError): From cb6b7a5fb9ff00b861c72be6313e3d64106a7e8c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 7 Apr 2021 07:26:54 +0200 Subject: [PATCH 133/219] standardized names --- src/homogenization.f90 | 24 ++++++++++++------------ src/homogenization_damage.f90 | 4 ++-- src/homogenization_thermal.f90 | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 3e4e18f56..7a931c793 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -117,6 +117,16 @@ module homogenization integer, intent(in) :: ho end subroutine mechanical_results + module subroutine damage_results(ho,group) + integer, intent(in) :: ho + character(len=*), intent(in) :: group + end subroutine damage_results + + module subroutine thermal_results(ho,group) + integer, intent(in) :: ho + character(len=*), intent(in) :: group + end subroutine thermal_results + module function mechanical_updateState(subdt,subF,ce) result(doneAndHappy) real(pReal), intent(in) :: & subdt !< current time step @@ -148,11 +158,6 @@ module homogenization real(pReal), intent(in) :: T, dot_T end subroutine homogenization_thermal_setField - module subroutine thermal_conduction_results(ho,group) - integer, intent(in) :: ho - character(len=*), intent(in) :: group - end subroutine thermal_conduction_results - module function homogenization_thermal_T(ce) result(T) integer, intent(in) :: ce real(pReal) :: T @@ -184,11 +189,6 @@ module homogenization phi end subroutine damage_nonlocal_putNonLocalDamage - module subroutine damage_nonlocal_results(ho,group) - integer, intent(in) :: ho - character(len=*), intent(in) :: group - end subroutine damage_nonlocal_results - end interface public :: & @@ -371,14 +371,14 @@ subroutine homogenization_results case(DAMAGE_NONLOCAL_ID) group = trim(group_base)//'/damage' call results_closeGroup(results_addGroup(group)) - call damage_nonlocal_results(ho,group) + call damage_results(ho,group) end select select case(thermal_type(ho)) case(THERMAL_CONDUCTION_ID) group = trim(group_base)//'/thermal' call results_closeGroup(results_addGroup(group)) - call thermal_conduction_results(ho,group) + call thermal_results(ho,group) end select enddo diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index 94978ccc8..ff8ab3976 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -153,7 +153,7 @@ end subroutine damage_nonlocal_putNonLocalDamage !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- -module subroutine damage_nonlocal_results(ho,group) +module subroutine damage_results(ho,group) integer, intent(in) :: ho character(len=*), intent(in) :: group @@ -170,6 +170,6 @@ module subroutine damage_nonlocal_results(ho,group) enddo outputsLoop end associate -end subroutine damage_nonlocal_results +end subroutine damage_results end submodule damage diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index 7bb81d24a..66acf40c2 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -193,7 +193,7 @@ end subroutine homogenization_thermal_setField !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- -module subroutine thermal_conduction_results(ho,group) +module subroutine thermal_results(ho,group) integer, intent(in) :: ho character(len=*), intent(in) :: group @@ -209,7 +209,7 @@ module subroutine thermal_conduction_results(ho,group) enddo outputsLoop end associate -end subroutine thermal_conduction_results +end subroutine thermal_results module function homogenization_thermal_T(ce) result(T) From 1fbf14c148772873a0146ebb4d262d1455edcd5a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 7 Apr 2021 07:52:57 +0200 Subject: [PATCH 134/219] encapsulation and namespace-like names --- src/grid/grid_thermal_spectral.f90 | 6 ++---- src/homogenization.f90 | 14 ++++---------- src/homogenization_thermal.f90 | 30 +++++++++++++++++++----------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/grid/grid_thermal_spectral.f90 b/src/grid/grid_thermal_spectral.f90 index dd431ad9b..14e2affb9 100644 --- a/src/grid/grid_thermal_spectral.f90 +++ b/src/grid/grid_thermal_spectral.f90 @@ -282,9 +282,7 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) ce = ce + 1 call thermal_conduction_getSource(Tdot,1,ce) scalarField_real(i,j,k) = params%timeinc*(scalarField_real(i,j,k) + Tdot) & - + thermal_conduction_getMassDensity (ce)* & - thermal_conduction_getSpecificHeat(ce)*(T_lastInc(i,j,k) - & - T_current(i,j,k))& + + homogenization_thermal_mu_T(ce) * (T_lastInc(i,j,k) - T_current(i,j,k)) & + mu_ref*T_current(i,j,k) enddo; enddo; enddo @@ -314,7 +312,7 @@ subroutine updateReference do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 K_ref = K_ref + thermal_conduction_getConductivity(ce) - mu_ref = mu_ref + thermal_conduction_getMassDensity(ce)* thermal_conduction_getSpecificHeat(ce) + mu_ref = mu_ref + homogenization_thermal_mu_T(ce) enddo; enddo; enddo K_ref = K_ref*wgt call MPI_Allreduce(MPI_IN_PLACE,K_ref,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 7a931c793..591bfc04e 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -143,15 +143,10 @@ module homogenization real(pReal), dimension(3,3) :: K end function thermal_conduction_getConductivity - module function thermal_conduction_getSpecificHeat(ce) result(c_P) + module function homogenization_thermal_mu_T(ce) result(mu_T) integer, intent(in) :: ce - real(pReal) :: c_P - end function thermal_conduction_getSpecificHeat - - module function thermal_conduction_getMassDensity(ce) result(rho) - integer, intent(in) :: ce - real(pReal) :: rho - end function thermal_conduction_getMassDensity + real(pReal) :: mu_T + end function homogenization_thermal_mu_T module subroutine homogenization_thermal_setField(T,dot_T, ce) integer, intent(in) :: ce @@ -194,9 +189,8 @@ module homogenization public :: & homogenization_init, & materialpoint_stressAndItsTangent, & - thermal_conduction_getSpecificHeat, & + homogenization_thermal_mu_T, & thermal_conduction_getConductivity, & - thermal_conduction_getMassDensity, & thermal_conduction_getSource, & damage_nonlocal_getMobility, & damage_nonlocal_getSourceAndItsTangent, & diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index 66acf40c2..95b58ec52 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -45,7 +45,7 @@ module subroutine thermal_init() print'(/,a)', ' <<<+- homogenization:thermal init -+>>>' - print'(/,a)', ' <<<+- homogenization:thermal:isotemperature init -+>>>' + print'(/,a)', ' <<<+- homogenization:thermal:isotemperature init -+>>>' @@ -128,10 +128,20 @@ module function thermal_conduction_getConductivity(ce) result(K) end function thermal_conduction_getConductivity +module function homogenization_thermal_mu_T(ce) result(mu_T) + + integer, intent(in) :: ce + real(pReal) :: mu_T + + mu_T = c_P(ce) * rho(ce) + +end function homogenization_thermal_mu_T + + !-------------------------------------------------------------------------------------------------- !> @brief returns homogenized specific heat capacity !-------------------------------------------------------------------------------------------------- -module function thermal_conduction_getSpecificHeat(ce) result(c_P) +function c_P(ce) integer, intent(in) :: ce real(pReal) :: c_P @@ -139,21 +149,20 @@ module function thermal_conduction_getSpecificHeat(ce) result(c_P) integer :: co - c_P = 0.0_pReal - - do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) + c_P = lattice_c_p(material_phaseID(1,ce)) + do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) c_P = c_P + lattice_c_p(material_phaseID(co,ce)) enddo c_P = c_P / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) -end function thermal_conduction_getSpecificHeat +end function c_P !-------------------------------------------------------------------------------------------------- !> @brief returns homogenized mass density !-------------------------------------------------------------------------------------------------- -module function thermal_conduction_getMassDensity(ce) result(rho) +function rho(ce) integer, intent(in) :: ce real(pReal) :: rho @@ -161,15 +170,14 @@ module function thermal_conduction_getMassDensity(ce) result(rho) integer :: co - rho = 0.0_pReal - - do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) + rho = lattice_rho(material_phaseID(1,ce)) + do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) rho = rho + lattice_rho(material_phaseID(co,ce)) enddo rho = rho / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) -end function thermal_conduction_getMassDensity +end function rho From c53927ad6f71793f4fb5e93247e753731c054f60 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 7 Apr 2021 08:47:46 +0200 Subject: [PATCH 135/219] not needed --- src/grid/grid_damage_spectral.f90 | 4 ++-- src/homogenization.f90 | 8 ++++---- src/homogenization_damage.f90 | 15 +++++++-------- src/homogenization_thermal.f90 | 2 +- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/grid/grid_damage_spectral.f90 b/src/grid/grid_damage_spectral.f90 index 6f99365f7..24aa4781a 100644 --- a/src/grid/grid_damage_spectral.f90 +++ b/src/grid/grid_damage_spectral.f90 @@ -259,7 +259,7 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) PetscObject :: dummy PetscErrorCode :: ierr integer :: i, j, k, ce - real(pReal) :: phiDot, dPhiDot_dPhi, mobility + real(pReal) :: phiDot, mobility phi_current = x_scal !-------------------------------------------------------------------------------------------------- @@ -281,7 +281,7 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) ce = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - call damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi_current(i,j,k),ce) + call damage_nonlocal_getSourceAndItsTangent(phiDot, phi_current(i,j,k),ce) mobility = damage_nonlocal_getMobility(ce) scalarField_real(i,j,k) = params%timeinc*(scalarField_real(i,j,k) + phiDot) & + mobility*(phi_lastInc(i,j,k) - phi_current(i,j,k)) & diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 591bfc04e..49addd098 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -170,12 +170,12 @@ module homogenization real(pReal) :: M end function damage_nonlocal_getMobility - module subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ce) + module subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, phi, ce) integer, intent(in) :: ce - real(pReal), intent(in) :: & + real(pReal), intent(in) :: & phi - real(pReal) :: & - phiDot, dPhiDot_dPhi + real(pReal), intent(out) :: & + phiDot end subroutine damage_nonlocal_getSourceAndItsTangent module subroutine damage_nonlocal_putNonLocalDamage(phi,ce) diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index ff8ab3976..53b5dd285 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -42,7 +42,7 @@ module subroutine damage_init() print'(/,a)', ' <<<+- homogenization:damage init -+>>>' - print'(/,a)', ' <<<+- homogenization:damage:isodamage init -+>>>' + print'(/,a)', ' <<<+- homogenization:damage:pass init -+>>>' configHomogenizations => config_material%get('homogenization') allocate(param(configHomogenizations%length)) @@ -113,20 +113,19 @@ end function damage_nonlocal_getMobility !-------------------------------------------------------------------------------------------------- !> @brief calculates homogenized damage driving forces !-------------------------------------------------------------------------------------------------- -module subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ce) +module subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, phi, ce) integer, intent(in) :: ce - real(pReal), intent(in) :: & + real(pReal), intent(in) :: & phi - real(pReal) :: & - phiDot, dPhiDot_dPhi + real(pReal), intent(out) :: & + phiDot - phiDot = 0.0_pReal - dPhiDot_dPhi = 0.0_pReal + real(pReal) :: & + dPhiDot_dPhi call phase_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ce) phiDot = phiDot/real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) - dPhiDot_dPhi = dPhiDot_dPhi/real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) end subroutine damage_nonlocal_getSourceAndItsTangent diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index 95b58ec52..8dcddda7a 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -45,7 +45,7 @@ module subroutine thermal_init() print'(/,a)', ' <<<+- homogenization:thermal init -+>>>' - print'(/,a)', ' <<<+- homogenization:thermal:isotemperature init -+>>>' + print'(/,a)', ' <<<+- homogenization:thermal:pass init -+>>>' From cdae867beb06391ccb91eccc19fc05e0678e1b7d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 7 Apr 2021 09:11:40 +0200 Subject: [PATCH 136/219] simplified damage currently works only for single constituent --- src/homogenization_damage.f90 | 22 ++------- src/phase.f90 | 11 ++--- src/phase_damage.f90 | 81 +++---------------------------- src/phase_damage_anisobrittle.f90 | 23 --------- src/phase_damage_anisoductile.f90 | 23 --------- src/phase_damage_isobrittle.f90 | 23 --------- src/phase_damage_isoductile.f90 | 23 --------- 7 files changed, 16 insertions(+), 190 deletions(-) diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index 53b5dd285..fa1eaab3f 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -76,14 +76,10 @@ module subroutine damage_partition(ce) real(pReal) :: phi integer, intent(in) :: ce - integer :: co - if(damageState_h(material_homogenizationID(ce))%sizeState < 1) return phi = damagestate_h(material_homogenizationID(ce))%state(1,material_homogenizationEntry(ce)) - do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) - call phase_damage_set_phi(phi,co,ce) - enddo + call phase_damage_set_phi(phi,1,ce) end subroutine damage_partition @@ -95,17 +91,9 @@ end subroutine damage_partition module function damage_nonlocal_getMobility(ce) result(M) integer, intent(in) :: ce - integer :: & - co real(pReal) :: M - M = 0.0_pReal - - do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) - M = M + lattice_M(material_phaseID(co,ce)) - enddo - - M = M/real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) + M = lattice_M(material_phaseID(1,ce)) end function damage_nonlocal_getMobility @@ -121,11 +109,7 @@ module subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, phi, ce) real(pReal), intent(out) :: & phiDot - real(pReal) :: & - dPhiDot_dPhi - - call phase_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ce) - phiDot = phiDot/real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) + phiDot = phase_damage_phi_dot(phi, ce) end subroutine damage_nonlocal_getSourceAndItsTangent diff --git a/src/phase.f90 b/src/phase.f90 index d10df84ba..d391e78cf 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -227,14 +227,13 @@ module phase end function phase_homogenizedC - module subroutine phase_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ce) + module function phase_damage_phi_dot(phi, ce) result(phi_dot) integer, intent(in) :: ce real(pReal), intent(in) :: & phi !< damage parameter - real(pReal), intent(inout) :: & - phiDot, & - dPhiDot_dPhi - end subroutine phase_damage_getRateAndItsTangents + real(pReal) :: & + phi_dot + end function phase_damage_phi_dot module subroutine phase_thermal_getRate(TDot, ph,me) integer, intent(in) :: ph, me @@ -301,7 +300,7 @@ module phase public :: & phase_init, & phase_homogenizedC, & - phase_damage_getRateAndItsTangents, & + phase_damage_phi_dot, & phase_thermal_getRate, & phase_results, & phase_allocateState, & diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index 4397d5cad..56f53c7bd 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -65,43 +65,6 @@ submodule(phase) damage integer, intent(in) :: ph,me end subroutine isoductile_dotState - - module subroutine anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph, me) - integer, intent(in) :: ph,me - real(pReal), intent(in) :: & - phi !< damage parameter - real(pReal), intent(out) :: & - localphiDot, & - dLocalphiDot_dPhi - end subroutine anisobrittle_getRateAndItsTangent - - module subroutine anisoductile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph,me) - integer, intent(in) :: ph,me - real(pReal), intent(in) :: & - phi !< damage parameter - real(pReal), intent(out) :: & - localphiDot, & - dLocalphiDot_dPhi - end subroutine anisoductile_getRateAndItsTangent - - module subroutine isobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph,me) - integer, intent(in) :: ph,me - real(pReal), intent(in) :: & - phi !< damage parameter - real(pReal), intent(out) :: & - localphiDot, & - dLocalphiDot_dPhi - end subroutine isobrittle_getRateAndItsTangent - - module subroutine isoductile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph,me) - integer, intent(in) :: ph,me - real(pReal), intent(in) :: & - phi !< damage parameter - real(pReal), intent(out) :: & - localphiDot, & - dLocalphiDot_dPhi - end subroutine isoductile_getRateAndItsTangent - module subroutine anisobrittle_results(phase,group) integer, intent(in) :: phase character(len=*), intent(in) :: group @@ -179,53 +142,25 @@ end subroutine damage_init !---------------------------------------------------------------------------------------------- !< @brief returns local part of nonlocal damage driving force !---------------------------------------------------------------------------------------------- -module subroutine phase_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ce) +module function phase_damage_phi_dot(phi, ce) result(phi_dot) integer, intent(in) :: ce real(pReal), intent(in) :: & phi !< damage parameter - real(pReal), intent(inout) :: & - phiDot, & - dPhiDot_dPhi - real(pReal) :: & - localphiDot, & - dLocalphiDot_dPhi + phi_dot + integer :: & ph, & - co, & me - phiDot = 0.0_pReal - dPhiDot_dPhi = 0.0_pReal + ph = material_phaseID(1,ce) + me = material_phaseEntry(1,ce) - do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) - ph = material_phaseID(co,ce) - me = material_phaseEntry(co,ce) + phi_dot = 1.0_pReal & + - phi*damageState(ph)%state(1,me) - select case(phase_source(ph)) - case (DAMAGE_ISOBRITTLE_ID) - call isobrittle_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, ph, me) - - case (DAMAGE_ISODUCTILE_ID) - call isoductile_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, ph, me) - - case (DAMAGE_ANISOBRITTLE_ID) - call anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph, me) - - case (DAMAGE_ANISODUCTILE_ID) - call anisoductile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph, me) - - case default - localphiDot = 0.0_pReal - dLocalphiDot_dPhi = 0.0_pReal - - end select - phiDot = phiDot + localphiDot - dPhiDot_dPhi = dPhiDot_dPhi + dLocalphiDot_dPhi - enddo - -end subroutine phase_damage_getRateAndItsTangents +end function phase_damage_phi_dot diff --git a/src/phase_damage_anisobrittle.f90 b/src/phase_damage_anisobrittle.f90 index e9672dd3b..d937255a5 100644 --- a/src/phase_damage_anisobrittle.f90 +++ b/src/phase_damage_anisobrittle.f90 @@ -148,29 +148,6 @@ module subroutine anisobrittle_dotState(S, ph,me) end subroutine anisobrittle_dotState -!-------------------------------------------------------------------------------------------------- -!> @brief returns local part of nonlocal damage driving force -!-------------------------------------------------------------------------------------------------- -module subroutine anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph, me) - - integer, intent(in) :: & - ph, & - me - real(pReal), intent(in) :: & - phi - real(pReal), intent(out) :: & - localphiDot, & - dLocalphiDot_dPhi - - - dLocalphiDot_dPhi = -damageState(ph)%state(1,me) - - localphiDot = 1.0_pReal & - + dLocalphiDot_dPhi*phi - -end subroutine anisobrittle_getRateAndItsTangent - - !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- diff --git a/src/phase_damage_anisoductile.f90 b/src/phase_damage_anisoductile.f90 index 54b63278f..049f148bc 100644 --- a/src/phase_damage_anisoductile.f90 +++ b/src/phase_damage_anisoductile.f90 @@ -113,29 +113,6 @@ module subroutine anisoductile_dotState(ph,me) end subroutine anisoductile_dotState -!-------------------------------------------------------------------------------------------------- -!> @brief returns local part of nonlocal damage driving force -!-------------------------------------------------------------------------------------------------- -module subroutine anisoductile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph,me) - - integer, intent(in) :: & - ph, & - me - real(pReal), intent(in) :: & - phi - real(pReal), intent(out) :: & - localphiDot, & - dLocalphiDot_dPhi - - - dLocalphiDot_dPhi = -damageState(ph)%state(1,me) - - localphiDot = 1.0_pReal & - + dLocalphiDot_dPhi*phi - -end subroutine anisoductile_getRateAndItsTangent - - !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- diff --git a/src/phase_damage_isobrittle.f90 b/src/phase_damage_isobrittle.f90 index 59cedb554..e88a87352 100644 --- a/src/phase_damage_isobrittle.f90 +++ b/src/phase_damage_isobrittle.f90 @@ -113,29 +113,6 @@ module subroutine isobrittle_deltaState(C, Fe, ph,me) end subroutine isobrittle_deltaState -!-------------------------------------------------------------------------------------------------- -!> @brief returns local part of nonlocal damage driving force -!-------------------------------------------------------------------------------------------------- -module subroutine isobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph, me) - - integer, intent(in) :: & - ph, me - real(pReal), intent(in) :: & - phi - real(pReal), intent(out) :: & - localphiDot, & - dLocalphiDot_dPhi - - - associate(prm => param(ph)) - localphiDot = 1.0_pReal & - - phi*damageState(ph)%state(1,me) - dLocalphiDot_dPhi = - damageState(ph)%state(1,me) - end associate - -end subroutine isobrittle_getRateAndItsTangent - - !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- diff --git a/src/phase_damage_isoductile.f90 b/src/phase_damage_isoductile.f90 index 1f1bba847..997b948fe 100644 --- a/src/phase_damage_isoductile.f90 +++ b/src/phase_damage_isoductile.f90 @@ -103,29 +103,6 @@ module subroutine isoductile_dotState(ph, me) end subroutine isoductile_dotState -!-------------------------------------------------------------------------------------------------- -!> @brief returns local part of nonlocal damage driving force -!-------------------------------------------------------------------------------------------------- -module subroutine isoductile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph, me) - - integer, intent(in) :: & - ph, & - me - real(pReal), intent(in) :: & - phi - real(pReal), intent(out) :: & - localphiDot, & - dLocalphiDot_dPhi - - - dLocalphiDot_dPhi = -damageState(ph)%state(1,me) - - localphiDot = 1.0_pReal & - + dLocalphiDot_dPhi*phi - -end subroutine isoductile_getRateAndItsTangent - - !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- From 5eb44969cc6d52a3458c90f27a815cd8b4197b44 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 7 Apr 2021 11:48:04 +0200 Subject: [PATCH 137/219] no need to do this globally --- src/homogenization.f90 | 14 ------------ src/homogenization_mechanical.f90 | 36 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 49addd098..f08b62560 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -515,14 +515,12 @@ end function damage_nonlocal_getDiffusion !-------------------------------------------------------------------------------------------------- !> @brief parses the homogenization part from the material configuration -! ToDo: This should be done in homogenization !-------------------------------------------------------------------------------------------------- subroutine material_parseHomogenization class(tNode), pointer :: & material_homogenization, & homog, & - homogMech, & homogThermal, & homogDamage @@ -530,23 +528,11 @@ subroutine material_parseHomogenization material_homogenization => config_material%get('homogenization') - allocate(homogenization_type(size(material_name_homogenization)), source=HOMOGENIZATION_undefined_ID) allocate(thermal_type(size(material_name_homogenization)), source=THERMAL_isothermal_ID) allocate(damage_type (size(material_name_homogenization)), source=DAMAGE_none_ID) do h=1, size(material_name_homogenization) homog => material_homogenization%get(h) - homogMech => homog%get('mechanical') - select case (homogMech%get_asString('type')) - case('pass') - homogenization_type(h) = HOMOGENIZATION_NONE_ID - case('isostrain') - homogenization_type(h) = HOMOGENIZATION_ISOSTRAIN_ID - case('RGC') - homogenization_type(h) = HOMOGENIZATION_RGC_ID - case default - call IO_error(500,ext_msg=homogMech%get_asString('type')) - end select if (homog%contains('thermal')) then homogThermal => homog%get('thermal') diff --git a/src/homogenization_mechanical.f90 b/src/homogenization_mechanical.f90 index 954aac403..3b75a66f0 100644 --- a/src/homogenization_mechanical.f90 +++ b/src/homogenization_mechanical.f90 @@ -86,6 +86,8 @@ module subroutine mechanical_init(num_homog) print'(/,a)', ' <<<+- homogenization:mechanical init -+>>>' + call material_parseHomogenization2() + allocate(homogenization_dPdF(3,3,3,3,discretization_nIPs*discretization_Nelems), source=0.0_pReal) homogenization_F0 = spread(math_I3,3,discretization_nIPs*discretization_Nelems) ! initialize to identity homogenization_F = homogenization_F0 ! initialize to identity @@ -244,4 +246,38 @@ module subroutine mechanical_results(group_base,ho) end subroutine mechanical_results +!-------------------------------------------------------------------------------------------------- +!> @brief parses the homogenization part from the material configuration +!-------------------------------------------------------------------------------------------------- +subroutine material_parseHomogenization2() + + class(tNode), pointer :: & + material_homogenization, & + homog, & + homogMech + + integer :: h + + material_homogenization => config_material%get('homogenization') + + allocate(homogenization_type(size(material_name_homogenization)), source=HOMOGENIZATION_undefined_ID) + + do h=1, size(material_name_homogenization) + homog => material_homogenization%get(h) + homogMech => homog%get('mechanical') + select case (homogMech%get_asString('type')) + case('pass') + homogenization_type(h) = HOMOGENIZATION_NONE_ID + case('isostrain') + homogenization_type(h) = HOMOGENIZATION_ISOSTRAIN_ID + case('RGC') + homogenization_type(h) = HOMOGENIZATION_RGC_ID + case default + call IO_error(500,ext_msg=homogMech%get_asString('type')) + end select + enddo + +end subroutine material_parseHomogenization2 + + end submodule mechanical From 16f7af4c27c2649898d281e74fe862f900d16169 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 7 Apr 2021 13:02:42 +0200 Subject: [PATCH 138/219] consistent interface --- src/homogenization_damage.f90 | 2 +- src/phase.f90 | 4 ++-- src/phase_damage.f90 | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index fa1eaab3f..0fe06e8fe 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -109,7 +109,7 @@ module subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, phi, ce) real(pReal), intent(out) :: & phiDot - phiDot = phase_damage_phi_dot(phi, ce) + phiDot = phase_damage_phi_dot(phi, 1, ce) end subroutine damage_nonlocal_getSourceAndItsTangent diff --git a/src/phase.f90 b/src/phase.f90 index d391e78cf..81e5ab250 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -227,8 +227,8 @@ module phase end function phase_homogenizedC - module function phase_damage_phi_dot(phi, ce) result(phi_dot) - integer, intent(in) :: ce + module function phase_damage_phi_dot(phi,co,ce) result(phi_dot) + integer, intent(in) :: ce,co real(pReal), intent(in) :: & phi !< damage parameter real(pReal) :: & diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index 56f53c7bd..4a1084cbf 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -142,9 +142,9 @@ end subroutine damage_init !---------------------------------------------------------------------------------------------- !< @brief returns local part of nonlocal damage driving force !---------------------------------------------------------------------------------------------- -module function phase_damage_phi_dot(phi, ce) result(phi_dot) +module function phase_damage_phi_dot(phi,co,ce) result(phi_dot) - integer, intent(in) :: ce + integer, intent(in) :: ce,co real(pReal), intent(in) :: & phi !< damage parameter real(pReal) :: & @@ -154,8 +154,8 @@ module function phase_damage_phi_dot(phi, ce) result(phi_dot) ph, & me - ph = material_phaseID(1,ce) - me = material_phaseEntry(1,ce) + ph = material_phaseID(co,ce) + me = material_phaseEntry(co,ce) phi_dot = 1.0_pReal & - phi*damageState(ph)%state(1,me) From c4942e3f823a96b8575db9523d95eaeda9d156d8 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 7 Apr 2021 13:22:22 +0200 Subject: [PATCH 139/219] part of damage init --- src/homogenization.f90 | 38 ----------------------------------- src/homogenization_damage.f90 | 23 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 39 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index f08b62560..9be7c0abf 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -205,7 +205,6 @@ module homogenization DAMAGE_NONLOCAL_ID public :: & - damage_nonlocal_init, & damage_nonlocal_getDiffusion contains @@ -236,8 +235,6 @@ subroutine homogenization_init() call mechanical_init(num_homog) call thermal_init() call damage_init() - call damage_nonlocal_init() - end subroutine homogenization_init @@ -452,41 +449,6 @@ subroutine homogenization_restartRead(fileHandle) end subroutine homogenization_restartRead - -!-------------------------------------------------------------------------------------------------- -!> @brief module initialization -!> @details reads in material parameters, allocates arrays, and does sanity checks -!-------------------------------------------------------------------------------------------------- -subroutine damage_nonlocal_init - - integer :: Ninstances,Nmaterialpoints,h - class(tNode), pointer :: & - num_generic, & - material_homogenization - - print'(/,a)', ' <<<+- damage_nonlocal init -+>>>'; flush(6) - -!------------------------------------------------------------------------------------ -! read numerics parameter - num_generic => config_numerics%get('generic',defaultVal= emptyDict) - num_damage%charLength = num_generic%get_asFloat('charLength',defaultVal=1.0_pReal) - - Ninstances = count(damage_type == DAMAGE_nonlocal_ID) - - material_homogenization => config_material%get('homogenization') - do h = 1, material_homogenization%length - if (damage_type(h) /= DAMAGE_NONLOCAL_ID) cycle - - Nmaterialpoints = count(material_homogenizationAt == h) - damageState_h(h)%sizeState = 1 - allocate(damageState_h(h)%state0 (1,Nmaterialpoints), source=1.0_pReal) - allocate(damageState_h(h)%state (1,Nmaterialpoints), source=1.0_pReal) - - enddo - -end subroutine damage_nonlocal_init - - !-------------------------------------------------------------------------------------------------- !> @brief returns homogenized non local damage diffusion tensor in reference configuration !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index 0fe06e8fe..c58d7d27e 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -37,8 +37,11 @@ module subroutine damage_init() class(tNode), pointer :: & configHomogenizations, & configHomogenization, & - configHomogenizationDamage + configHomogenizationDamage, & + num_generic, & + material_homogenization integer :: ho + integer :: Ninstances,Nmaterialpoints,h print'(/,a)', ' <<<+- homogenization:damage init -+>>>' @@ -65,6 +68,24 @@ module subroutine damage_init() end associate enddo +!------------------------------------------------------------------------------------ +! read numerics parameter + num_generic => config_numerics%get('generic',defaultVal= emptyDict) + num_damage%charLength = num_generic%get_asFloat('charLength',defaultVal=1.0_pReal) + + Ninstances = count(damage_type == DAMAGE_nonlocal_ID) + + material_homogenization => config_material%get('homogenization') + do h = 1, material_homogenization%length + if (damage_type(h) /= DAMAGE_NONLOCAL_ID) cycle + + Nmaterialpoints = count(material_homogenizationAt == h) + damageState_h(h)%sizeState = 1 + allocate(damageState_h(h)%state0 (1,Nmaterialpoints), source=1.0_pReal) + allocate(damageState_h(h)%state (1,Nmaterialpoints), source=1.0_pReal) + + enddo + end subroutine damage_init From 6fcc4f91154bdb5579c4b4b6aa47d39ea65c9ae0 Mon Sep 17 00:00:00 2001 From: Test User Date: Wed, 7 Apr 2021 14:36:00 +0200 Subject: [PATCH 140/219] [skip ci] updated version information after successful test of v3.0.0-alpha2-767-g3c967abcd --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 149e4ab91..a4ae6ed29 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-756-g39f4efa55 +v3.0.0-alpha2-767-g3c967abcd From 1851b66cb4b9791a5792db8eb318c81bd2549de0 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 7 Apr 2021 14:56:11 +0200 Subject: [PATCH 141/219] use new data container --- src/homogenization_damage.f90 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index c58d7d27e..59f39ce9f 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -150,6 +150,7 @@ module subroutine damage_nonlocal_putNonLocalDamage(phi,ce) ho = material_homogenizationID(ce) en = material_homogenizationEntry(ce) damagestate_h(ho)%state(1,en) = phi + current(ho)%phi(en) = phi end subroutine damage_nonlocal_putNonLocalDamage From bbb292d09312f4c1401f935842b48d9578f324af Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 7 Apr 2021 20:39:11 +0200 Subject: [PATCH 142/219] polishing --- src/IO.f90 | 4 ++-- src/YAML_types.f90 | 2 +- src/homogenization.f90 | 2 -- src/homogenization_mechanical.f90 | 3 +++ src/phase.f90 | 4 +--- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/IO.f90 b/src/IO.f90 index b6dbf5664..9ea35503b 100644 --- a/src/IO.f90 +++ b/src/IO.f90 @@ -604,7 +604,7 @@ subroutine IO_warning(warning_ID,el,ip,g,ext_msg) msg = 'read only the first document' case default msg = 'unknown warning number' - end select + end select !$OMP CRITICAL (write2out) write(IO_STDERR,'(/,a)') ' ┌'//IO_DIVIDER//'┐' @@ -658,7 +658,7 @@ subroutine selfTest if(any([1,1,1] /= IO_stringPos('a'))) error stop 'IO_stringPos' if(any([2,2,3,5,5] /= IO_stringPos(' aa b'))) error stop 'IO_stringPos' - str=' 1.0 xxx' + str = ' 1.0 xxx' chunkPos = IO_stringPos(str) if(dNeq(1.0_pReal,IO_floatValue(str,chunkPos,1))) error stop 'IO_floatValue' diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index 3d83831e6..2a6bd64f9 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -266,7 +266,7 @@ subroutine selfTest if(any(dNeq(l2%get_as1dFloat(1),[2.0_pReal,3.0_pReal]))) error stop 'byIndex_as1dFloat' call l2%append(l3) x = l2%as2dFloat() - if(x(2,1)/= 4.0_pReal) error stop 'byKey_as2dFloat' + if(dNeq(x(2,1),4.0_pReal)) error stop 'byKey_as2dFloat' if(any(dNeq(pack(l2%as2dFloat(),.true.),& [2.0_pReal,4.0_pReal,3.0_pReal,5.0_pReal]))) error stop 'byKey_as2dFloat' n => l2 diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 9be7c0abf..e5d3d034e 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -39,8 +39,6 @@ module homogenization thermal_type !< thermal transport model integer(kind(DAMAGE_none_ID)), dimension(:), allocatable :: & damage_type !< nonlocal damage model - integer(kind(HOMOGENIZATION_undefined_ID)), dimension(:), allocatable :: & - homogenization_type !< type of each homogenization type, private :: tNumerics_damage real(pReal) :: & diff --git a/src/homogenization_mechanical.f90 b/src/homogenization_mechanical.f90 index 3b75a66f0..c19695d3d 100644 --- a/src/homogenization_mechanical.f90 +++ b/src/homogenization_mechanical.f90 @@ -71,6 +71,9 @@ submodule(homogenization) mechanical end interface + integer(kind(HOMOGENIZATION_undefined_ID)), dimension(:), allocatable :: & + homogenization_type !< type of each homogenization + contains !-------------------------------------------------------------------------------------------------- diff --git a/src/phase.f90 b/src/phase.f90 index 81e5ab250..c95e828b4 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -332,8 +332,7 @@ contains subroutine phase_init integer :: & - ph, & !< counter in phase loop - so !< counter in source loop + ph class (tNode), pointer :: & debug_constitutive, & materials, & @@ -475,7 +474,6 @@ subroutine crystallite_init() co, & !< counter in integration point component loop ip, & !< counter in integration point loop el, & !< counter in element loop - so, & cMax, & !< maximum number of integration point components iMax, & !< maximum number of integration points eMax !< maximum number of elements From c4b4ea8c21c7041cc5dd0ec8ea537c4923500bfa Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 7 Apr 2021 20:52:25 +0200 Subject: [PATCH 143/219] avoid invalid access in case of no damage --- src/phase_damage.f90 | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index 4a1084cbf..62ce70368 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -152,13 +152,18 @@ module function phase_damage_phi_dot(phi,co,ce) result(phi_dot) integer :: & ph, & - me + en ph = material_phaseID(co,ce) - me = material_phaseEntry(co,ce) + en = material_phaseEntry(co,ce) - phi_dot = 1.0_pReal & - - phi*damageState(ph)%state(1,me) + select case(phase_source(ph)) + case(DAMAGE_ISOBRITTLE_ID,DAMAGE_ISODUCTILE_ID,DAMAGE_ANISOBRITTLE_ID,DAMAGE_ANISODUCTILE_ID) + phi_dot = 1.0_pReal & + - phi*damageState(ph)%state(1,en) + case default + phi_dot = 0.0_pReal + end select end function phase_damage_phi_dot From 0fc7f66ef8c89c5ac6c174f080bf729a79a013d6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 7 Apr 2021 21:06:29 +0200 Subject: [PATCH 144/219] consistent names --- src/grid/grid_damage_spectral.f90 | 4 +-- src/homogenization.f90 | 6 ++--- src/homogenization_damage.f90 | 4 +-- src/homogenization_mechanical.f90 | 12 ++++----- src/phase.f90 | 20 +++++++-------- src/phase_damage_anisobrittle.f90 | 3 --- src/phase_mechanical.f90 | 41 ++++++++++++++++--------------- src/phase_mechanical_eigen.f90 | 1 - 8 files changed, 44 insertions(+), 47 deletions(-) diff --git a/src/grid/grid_damage_spectral.f90 b/src/grid/grid_damage_spectral.f90 index 24aa4781a..002a15708 100644 --- a/src/grid/grid_damage_spectral.f90 +++ b/src/grid/grid_damage_spectral.f90 @@ -196,7 +196,7 @@ function grid_damage_spectral_solution(timeinc) result(solution) ce = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - call damage_nonlocal_putNonLocalDamage(phi_current(i,j,k),ce) + call homogenization_set_phi(phi_current(i,j,k),ce) enddo; enddo; enddo call VecMin(solution_vec,devNull,phi_min,ierr); CHKERRQ(ierr) @@ -233,7 +233,7 @@ subroutine grid_damage_spectral_forward(cutBack) call DMDAVecRestoreArrayF90(dm_local,solution_vec,x_scal,ierr); CHKERRQ(ierr) do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - call damage_nonlocal_putNonLocalDamage(phi_current(i,j,k),ce) + call homogenization_set_phi(phi_current(i,j,k),ce) enddo; enddo; enddo else phi_lastInc = phi_current diff --git a/src/homogenization.f90 b/src/homogenization.f90 index e5d3d034e..4ce75feca 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -176,11 +176,11 @@ module homogenization phiDot end subroutine damage_nonlocal_getSourceAndItsTangent - module subroutine damage_nonlocal_putNonLocalDamage(phi,ce) + module subroutine homogenization_set_phi(phi,ce) integer, intent(in) :: ce real(pReal), intent(in) :: & phi - end subroutine damage_nonlocal_putNonLocalDamage + end subroutine homogenization_set_phi end interface @@ -192,7 +192,7 @@ module homogenization thermal_conduction_getSource, & damage_nonlocal_getMobility, & damage_nonlocal_getSourceAndItsTangent, & - damage_nonlocal_putNonLocalDamage, & + homogenization_set_phi, & homogenization_thermal_setfield, & homogenization_thermal_T, & homogenization_forward, & diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index 59f39ce9f..a067dde43 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -138,7 +138,7 @@ end subroutine damage_nonlocal_getSourceAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief updated nonlocal damage field with solution from damage phase field PDE !-------------------------------------------------------------------------------------------------- -module subroutine damage_nonlocal_putNonLocalDamage(phi,ce) +module subroutine homogenization_set_phi(phi,ce) integer, intent(in) :: ce real(pReal), intent(in) :: & @@ -152,7 +152,7 @@ module subroutine damage_nonlocal_putNonLocalDamage(phi,ce) damagestate_h(ho)%state(1,en) = phi current(ho)%phi(en) = phi -end subroutine damage_nonlocal_putNonLocalDamage +end subroutine homogenization_set_phi !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization_mechanical.f90 b/src/homogenization_mechanical.f90 index c19695d3d..7d1c64445 100644 --- a/src/homogenization_mechanical.f90 +++ b/src/homogenization_mechanical.f90 @@ -132,7 +132,7 @@ module subroutine mechanical_partition(subF,ce) end select chosenHomogenization do co = 1,homogenization_Nconstituents(material_homogenizationID(ce)) - call phase_mechanical_setF(Fs(1:3,1:3,co),co,ce) + call phase_set_F(Fs(1:3,1:3,co),co,ce) enddo @@ -155,13 +155,13 @@ module subroutine mechanical_homogenize(dt,ce) chosenHomogenization: select case(homogenization_type(material_homogenizationID(ce))) case (HOMOGENIZATION_NONE_ID) chosenHomogenization - homogenization_P(1:3,1:3,ce) = phase_mechanical_getP(1,ce) + homogenization_P(1:3,1:3,ce) = phase_P(1,ce) homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = phase_mechanical_dPdF(dt,1,ce) case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(dt,co,ce) - Ps(:,:,co) = phase_mechanical_getP(co,ce) + Ps(:,:,co) = phase_P(co,ce) enddo call isostrain_averageStressAndItsTangent(& homogenization_P(1:3,1:3,ce), & @@ -172,7 +172,7 @@ module subroutine mechanical_homogenize(dt,ce) case (HOMOGENIZATION_RGC_ID) chosenHomogenization do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(dt,co,ce) - Ps(:,:,co) = phase_mechanical_getP(co,ce) + Ps(:,:,co) = phase_P(co,ce) enddo call RGC_averageStressAndItsTangent(& homogenization_P(1:3,1:3,ce), & @@ -208,8 +208,8 @@ module function mechanical_updateState(subdt,subF,ce) result(doneAndHappy) if (homogenization_type(material_homogenizationID(ce)) == HOMOGENIZATION_RGC_ID) then do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(subdt,co,ce) - Fs(:,:,co) = phase_mechanical_getF(co,ce) - Ps(:,:,co) = phase_mechanical_getP(co,ce) + Fs(:,:,co) = phase_F(co,ce) + Ps(:,:,co) = phase_P(co,ce) enddo doneAndHappy = RGC_updateState(Ps,Fs,subF,subdt,dPdFs,ce) else diff --git a/src/phase.f90 b/src/phase.f90 index c95e828b4..1adba03d9 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -145,20 +145,20 @@ module phase real(pReal), dimension(3,3) :: L_p end function mechanical_L_p - module function phase_mechanical_getF(co,ce) result(F) + module function phase_F(co,ce) result(F) integer, intent(in) :: co, ce real(pReal), dimension(3,3) :: F - end function phase_mechanical_getF + end function phase_F module function mechanical_F_e(ph,me) result(F_e) integer, intent(in) :: ph,me real(pReal), dimension(3,3) :: F_e end function mechanical_F_e - module function phase_mechanical_getP(co,ce) result(P) + module function phase_P(co,ce) result(P) integer, intent(in) :: co, ce real(pReal), dimension(3,3) :: P - end function phase_mechanical_getP + end function phase_P module function phase_damage_get_phi(co,ip,el) result(phi) integer, intent(in) :: co, ip, el @@ -181,10 +181,10 @@ module phase end function damage_phi - module subroutine phase_mechanical_setF(F,co,ce) + module subroutine phase_set_F(F,co,ce) real(pReal), dimension(3,3), intent(in) :: F integer, intent(in) :: co, ce - end subroutine phase_mechanical_setF + end subroutine phase_set_F module subroutine phase_thermal_setField(T,dot_T, co,ce) real(pReal), intent(in) :: T, dot_T @@ -320,9 +320,9 @@ module phase phase_thermal_setField, & phase_damage_set_phi, & phase_damage_get_phi, & - phase_mechanical_getP, & - phase_mechanical_setF, & - phase_mechanical_getF + phase_P, & + phase_set_F, & + phase_F contains @@ -588,7 +588,7 @@ function crystallite_push33ToRef(co,ce, tensor33) ph = material_phaseID(co,ce) en = material_phaseEntry(co,ce) - T = matmul(material_orientation0(co,ph,en)%asMatrix(),transpose(math_inv33(phase_mechanical_getF(co,ce)))) ! ToDo: initial orientation correct? + T = matmul(material_orientation0(co,ph,en)%asMatrix(),transpose(math_inv33(phase_F(co,ce)))) ! ToDo: initial orientation correct? crystallite_push33ToRef = matmul(transpose(T),matmul(tensor33,T)) diff --git a/src/phase_damage_anisobrittle.f90 b/src/phase_damage_anisobrittle.f90 index d937255a5..ddcca9044 100644 --- a/src/phase_damage_anisobrittle.f90 +++ b/src/phase_damage_anisobrittle.f90 @@ -120,9 +120,6 @@ module subroutine anisobrittle_dotState(S, ph,me) S integer :: & - sourceOffset, & - damageOffset, & - homog, & i real(pReal) :: & traction_d, traction_t, traction_n, traction_crit diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index ddd6e1fcb..9f2bc4df2 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -1421,20 +1421,6 @@ module function mechanical_L_p(ph,me) result(L_p) end function mechanical_L_p -!---------------------------------------------------------------------------------------------- -!< @brief Get deformation gradient (for use by homogenization) -!---------------------------------------------------------------------------------------------- -module function phase_mechanical_getF(co,ce) result(F) - - integer, intent(in) :: co, ce - real(pReal), dimension(3,3) :: F - - - F = phase_mechanical_F(material_phaseID(co,ce))%data(1:3,1:3,material_phaseEntry(co,ce)) - -end function phase_mechanical_getF - - !---------------------------------------------------------------------------------------------- !< @brief Get elastic deformation gradient (for use by non-mech physics) !---------------------------------------------------------------------------------------------- @@ -1449,11 +1435,10 @@ module function mechanical_F_e(ph,me) result(F_e) end function mechanical_F_e - !---------------------------------------------------------------------------------------------- !< @brief Get second Piola-Kichhoff stress (for use by homogenization) !---------------------------------------------------------------------------------------------- -module function phase_mechanical_getP(co,ce) result(P) +module function phase_P(co,ce) result(P) integer, intent(in) :: co, ce real(pReal), dimension(3,3) :: P @@ -1461,11 +1446,27 @@ module function phase_mechanical_getP(co,ce) result(P) P = phase_mechanical_P(material_phaseID(co,ce))%data(1:3,1:3,material_phaseEntry(co,ce)) -end function phase_mechanical_getP +end function phase_P -! setter for homogenization -module subroutine phase_mechanical_setF(F,co,ce) +!---------------------------------------------------------------------------------------------- +!< @brief Get deformation gradient (for use by homogenization) +!---------------------------------------------------------------------------------------------- +module function phase_F(co,ce) result(F) + + integer, intent(in) :: co, ce + real(pReal), dimension(3,3) :: F + + + F = phase_mechanical_F(material_phaseID(co,ce))%data(1:3,1:3,material_phaseEntry(co,ce)) + +end function phase_F + + +!---------------------------------------------------------------------------------------------- +!< @brief Set deformation gradient (for use by homogenization) +!---------------------------------------------------------------------------------------------- +module subroutine phase_set_F(F,co,ce) real(pReal), dimension(3,3), intent(in) :: F integer, intent(in) :: co, ce @@ -1473,7 +1474,7 @@ module subroutine phase_mechanical_setF(F,co,ce) phase_mechanical_F(material_phaseID(co,ce))%data(1:3,1:3,material_phaseEntry(co,ce)) = F -end subroutine phase_mechanical_setF +end subroutine phase_set_F end submodule mechanical diff --git a/src/phase_mechanical_eigen.f90 b/src/phase_mechanical_eigen.f90 index 3f2aec58c..7c4e70c1c 100644 --- a/src/phase_mechanical_eigen.f90 +++ b/src/phase_mechanical_eigen.f90 @@ -46,7 +46,6 @@ module subroutine eigendeformation_init(phases) class(tNode), pointer :: & phase, & kinematics, & - damage, & mechanics print'(/,a)', ' <<<+- phase:mechanical:eigen init -+>>>' From d59051f57670770c2653bdf4f6b3c6e3418ea2eb Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 7 Apr 2021 22:41:49 +0200 Subject: [PATCH 145/219] systematic names --- src/grid/grid_thermal_spectral.f90 | 8 +++--- src/homogenization.f90 | 24 ++++++++--------- src/homogenization_thermal.f90 | 36 ++++++++++--------------- src/phase.f90 | 9 +++---- src/phase_thermal.f90 | 42 +++++++++++++----------------- src/phase_thermal_dissipation.f90 | 10 +++---- src/phase_thermal_externalheat.f90 | 12 ++++----- 7 files changed, 61 insertions(+), 80 deletions(-) diff --git a/src/grid/grid_thermal_spectral.f90 b/src/grid/grid_thermal_spectral.f90 index 14e2affb9..7d4878b12 100644 --- a/src/grid/grid_thermal_spectral.f90 +++ b/src/grid/grid_thermal_spectral.f90 @@ -258,7 +258,6 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) PetscObject :: dummy PetscErrorCode :: ierr integer :: i, j, k, ce - real(pReal) :: Tdot T_current = x_scal !-------------------------------------------------------------------------------------------------- @@ -271,7 +270,7 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) ce = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - vectorField_real(1:3,i,j,k) = matmul(thermal_conduction_getConductivity(ce) - K_ref, & + vectorField_real(1:3,i,j,k) = matmul(homogenization_K(ce) - K_ref, & vectorField_real(1:3,i,j,k)) enddo; enddo; enddo call utilities_FFTvectorForward @@ -280,8 +279,7 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) ce = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - call thermal_conduction_getSource(Tdot,1,ce) - scalarField_real(i,j,k) = params%timeinc*(scalarField_real(i,j,k) + Tdot) & + scalarField_real(i,j,k) = params%timeinc*(scalarField_real(i,j,k) + homogenization_f_T(ce)) & + homogenization_thermal_mu_T(ce) * (T_lastInc(i,j,k) - T_current(i,j,k)) & + mu_ref*T_current(i,j,k) enddo; enddo; enddo @@ -311,7 +309,7 @@ subroutine updateReference mu_ref = 0.0_pReal do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - K_ref = K_ref + thermal_conduction_getConductivity(ce) + K_ref = K_ref + homogenization_K(ce) mu_ref = mu_ref + homogenization_thermal_mu_T(ce) enddo; enddo; enddo K_ref = K_ref*wgt diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 4ce75feca..478efad53 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -136,10 +136,10 @@ module homogenization end function mechanical_updateState - module function thermal_conduction_getConductivity(ce) result(K) + module function homogenization_K(ce) result(K) integer, intent(in) :: ce real(pReal), dimension(3,3) :: K - end function thermal_conduction_getConductivity + end function homogenization_K module function homogenization_thermal_mu_T(ce) result(mu_T) integer, intent(in) :: ce @@ -151,17 +151,15 @@ module homogenization real(pReal), intent(in) :: T, dot_T end subroutine homogenization_thermal_setField - module function homogenization_thermal_T(ce) result(T) + module function homogenization_T(ce) result(T) integer, intent(in) :: ce real(pReal) :: T - end function homogenization_thermal_T + end function homogenization_T - module subroutine thermal_conduction_getSource(Tdot, ip, el) - integer, intent(in) :: & - ip, & - el - real(pReal), intent(out) :: Tdot - end subroutine thermal_conduction_getSource + module function homogenization_f_T(ce) result(f_T) + integer, intent(in) :: ce + real(pReal) :: f_T + end function homogenization_f_T module function damage_nonlocal_getMobility(ce) result(M) integer, intent(in) :: ce @@ -188,13 +186,13 @@ module homogenization homogenization_init, & materialpoint_stressAndItsTangent, & homogenization_thermal_mu_T, & - thermal_conduction_getConductivity, & - thermal_conduction_getSource, & + homogenization_K, & + homogenization_f_T, & damage_nonlocal_getMobility, & damage_nonlocal_getSourceAndItsTangent, & homogenization_set_phi, & homogenization_thermal_setfield, & - homogenization_thermal_T, & + homogenization_T, & homogenization_forward, & homogenization_results, & homogenization_restartRead, & diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index 8dcddda7a..a372a7494 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -109,7 +109,7 @@ end subroutine thermal_homogenize !-------------------------------------------------------------------------------------------------- !> @brief return homogenized thermal conductivity in reference configuration !-------------------------------------------------------------------------------------------------- -module function thermal_conduction_getConductivity(ce) result(K) +module function homogenization_K(ce) result(K) integer, intent(in) :: ce real(pReal), dimension(3,3) :: K @@ -125,11 +125,11 @@ module function thermal_conduction_getConductivity(ce) result(K) K = K / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) -end function thermal_conduction_getConductivity +end function homogenization_K module function homogenization_thermal_mu_T(ce) result(mu_T) - + integer, intent(in) :: ce real(pReal) :: mu_T @@ -220,43 +220,35 @@ module subroutine thermal_results(ho,group) end subroutine thermal_results -module function homogenization_thermal_T(ce) result(T) +module function homogenization_T(ce) result(T) integer, intent(in) :: ce real(pReal) :: T T = current(material_homogenizationID(ce))%T(material_homogenizationEntry(ce)) -end function homogenization_thermal_T +end function homogenization_T !-------------------------------------------------------------------------------------------------- !> @brief return heat generation rate !-------------------------------------------------------------------------------------------------- -module subroutine thermal_conduction_getSource(Tdot, ip, el) +module function homogenization_f_T(ce) result(f_T) - integer, intent(in) :: & - ip, & - el - real(pReal), intent(out) :: & - Tdot + integer, intent(in) :: ce + real(pReal) :: f_T - integer :: co, ho,ph,me - real(pReal) :: dot_T_temp + integer :: co - ho = material_homogenizationAt(el) - Tdot = 0.0_pReal - do co = 1, homogenization_Nconstituents(ho) - ph = material_phaseAt(co,el) - me = material_phasememberAt(co,ip,el) - call phase_thermal_getRate(dot_T_temp, ph,me) - Tdot = Tdot + dot_T_temp + f_T = phase_f_T(material_phaseID(1,ce),material_phaseEntry(1,ce)) + do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) + f_T = f_T + phase_f_T(material_phaseID(co,ce),material_phaseEntry(co,ce)) enddo - Tdot = Tdot/real(homogenization_Nconstituents(ho),pReal) + f_T = f_T/real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) -end subroutine thermal_conduction_getSource +end function homogenization_f_T end submodule thermal diff --git a/src/phase.f90 b/src/phase.f90 index 1adba03d9..dce63a5ac 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -235,11 +235,10 @@ module phase phi_dot end function phase_damage_phi_dot - module subroutine phase_thermal_getRate(TDot, ph,me) + module function phase_f_T(ph,me) result(f_T) integer, intent(in) :: ph, me - real(pReal), intent(out) :: & - TDot - end subroutine phase_thermal_getRate + real(pReal) :: f_T + end function phase_f_T module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,i,e) integer, intent(in) :: & @@ -301,7 +300,7 @@ module phase phase_init, & phase_homogenizedC, & phase_damage_phi_dot, & - phase_thermal_getRate, & + phase_f_T, & phase_results, & phase_allocateState, & phase_forward, & diff --git a/src/phase_thermal.f90 b/src/phase_thermal.f90 index 1e157f338..e7f9abdc5 100644 --- a/src/phase_thermal.f90 +++ b/src/phase_thermal.f90 @@ -21,7 +21,7 @@ submodule(phase) thermal integer(kind(THERMAL_UNDEFINED_ID)), dimension(:,:), allocatable :: & thermal_source - type(tDataContainer), dimension(:), allocatable :: current ! ?? not very telling name. Better: "field" ?? + type(tDataContainer), dimension(:), allocatable :: current ! ?? not very telling name. Better: "field" ?? MD: current(ho)%T(me) reads quite good integer :: thermal_source_maxSizeDotState @@ -45,21 +45,19 @@ submodule(phase) thermal me end subroutine externalheat_dotState - module subroutine dissipation_getRate(TDot, ph,me) + module function dissipation_f_T(ph,me) result(f_T) integer, intent(in) :: & ph, & me - real(pReal), intent(out) :: & - TDot - end subroutine dissipation_getRate + real(pReal) :: f_T + end function dissipation_f_T - module subroutine externalheat_getRate(TDot, ph,me) + module function externalheat_f_T(ph,me) result(f_T) integer, intent(in) :: & ph, & me - real(pReal), intent(out) :: & - TDot - end subroutine externalheat_getRate + real(pReal) :: f_T + end function externalheat_f_T end interface @@ -123,35 +121,31 @@ end subroutine thermal_init !---------------------------------------------------------------------------------------------- !< @brief calculates thermal dissipation rate !---------------------------------------------------------------------------------------------- -module subroutine phase_thermal_getRate(TDot, ph,me) +module function phase_f_T(ph,me) result(f_T) integer, intent(in) :: ph, me - real(pReal), intent(out) :: & - TDot - - real(pReal) :: & - my_Tdot - integer :: & - so + real(pReal) :: f_T - TDot = 0.0_pReal + integer :: so + + + f_T = 0.0_pReal do so = 1, thermal_Nsources(ph) select case(thermal_source(so,ph)) + case (THERMAL_DISSIPATION_ID) - call dissipation_getRate(my_Tdot, ph,me) + f_T = f_T + dissipation_f_T(ph,me) case (THERMAL_EXTERNALHEAT_ID) - call externalheat_getRate(my_Tdot, ph,me) + f_T = f_T + externalheat_f_T(ph,me) - case default - my_Tdot = 0.0_pReal end select - Tdot = Tdot + my_Tdot + enddo -end subroutine phase_thermal_getRate +end function phase_f_T !-------------------------------------------------------------------------------------------------- diff --git a/src/phase_thermal_dissipation.f90 b/src/phase_thermal_dissipation.f90 index b16ed3cf7..3a4ee651a 100644 --- a/src/phase_thermal_dissipation.f90 +++ b/src/phase_thermal_dissipation.f90 @@ -69,17 +69,17 @@ end function dissipation_init !-------------------------------------------------------------------------------------------------- !> @brief Ninstancess dissipation rate !-------------------------------------------------------------------------------------------------- -module subroutine dissipation_getRate(TDot, ph,me) +module function dissipation_f_T(ph,me) result(f_T) integer, intent(in) :: ph, me - real(pReal), intent(out) :: & - TDot + real(pReal) :: & + f_T associate(prm => param(ph)) - TDot = prm%kappa*sum(abs(mechanical_S(ph,me)*mechanical_L_p(ph,me))) + f_T = prm%kappa*sum(abs(mechanical_S(ph,me)*mechanical_L_p(ph,me))) end associate -end subroutine dissipation_getRate +end function dissipation_f_T end submodule dissipation diff --git a/src/phase_thermal_externalheat.f90 b/src/phase_thermal_externalheat.f90 index d5bbc7c38..6d4403ab8 100644 --- a/src/phase_thermal_externalheat.f90 +++ b/src/phase_thermal_externalheat.f90 @@ -100,13 +100,13 @@ end subroutine externalheat_dotState !-------------------------------------------------------------------------------------------------- !> @brief returns local heat generation rate !-------------------------------------------------------------------------------------------------- -module subroutine externalheat_getRate(TDot, ph, me) +module function externalheat_f_T(ph,me) result(f_T) integer, intent(in) :: & ph, & me - real(pReal), intent(out) :: & - TDot + real(pReal) :: & + f_T integer :: & so, interval @@ -122,12 +122,12 @@ module subroutine externalheat_getRate(TDot, ph, me) if ( (frac_time < 0.0_pReal .and. interval == 1) & .or. (frac_time >= 1.0_pReal .and. interval == prm%nIntervals) & .or. (frac_time >= 0.0_pReal .and. frac_time < 1.0_pReal) ) & - TDot = prm%f_T(interval ) * (1.0_pReal - frac_time) + & - prm%f_T(interval+1) * frac_time ! interpolate heat rate between segment boundaries... + f_T = prm%f_T(interval ) * (1.0_pReal - frac_time) + & + prm%f_T(interval+1) * frac_time ! interpolate heat rate between segment boundaries... ! ...or extrapolate if outside me bounds enddo end associate -end subroutine externalheat_getRate +end function externalheat_f_T end submodule externalheat From c4765d3742076187d4742d387b18b3f7d64b037b Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 8 Apr 2021 13:31:21 +0200 Subject: [PATCH 146/219] following paper --- src/grid/grid_damage_spectral.f90 | 13 ++++++------ src/homogenization.f90 | 34 +++++++++++++++---------------- src/homogenization_damage.f90 | 15 +++++++------- src/phase.f90 | 29 +++++++++++--------------- src/phase_damage.f90 | 18 ++++------------ 5 files changed, 45 insertions(+), 64 deletions(-) diff --git a/src/grid/grid_damage_spectral.f90 b/src/grid/grid_damage_spectral.f90 index 002a15708..7e0d4112a 100644 --- a/src/grid/grid_damage_spectral.f90 +++ b/src/grid/grid_damage_spectral.f90 @@ -259,7 +259,7 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) PetscObject :: dummy PetscErrorCode :: ierr integer :: i, j, k, ce - real(pReal) :: phiDot, mobility + real(pReal) :: mobility phi_current = x_scal !-------------------------------------------------------------------------------------------------- @@ -272,7 +272,7 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) ce = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - vectorField_real(1:3,i,j,k) = matmul(damage_nonlocal_getDiffusion(ce) - K_ref, & + vectorField_real(1:3,i,j,k) = matmul(homogenization_K_phi(ce) - K_ref, & vectorField_real(1:3,i,j,k)) enddo; enddo; enddo call utilities_FFTvectorForward @@ -281,9 +281,8 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) ce = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - call damage_nonlocal_getSourceAndItsTangent(phiDot, phi_current(i,j,k),ce) - mobility = damage_nonlocal_getMobility(ce) - scalarField_real(i,j,k) = params%timeinc*(scalarField_real(i,j,k) + phiDot) & + mobility = homogenization_mu_phi(ce) + scalarField_real(i,j,k) = params%timeinc*(scalarField_real(i,j,k) + homogenization_f_phi(phi_current(i,j,k),ce)) & + mobility*(phi_lastInc(i,j,k) - phi_current(i,j,k)) & + mu_ref*phi_current(i,j,k) enddo; enddo; enddo @@ -317,8 +316,8 @@ subroutine updateReference mu_ref = 0.0_pReal do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - K_ref = K_ref + damage_nonlocal_getDiffusion(ce) - mu_ref = mu_ref + damage_nonlocal_getMobility(ce) + K_ref = K_ref + homogenization_K_phi(ce) + mu_ref = mu_ref + homogenization_mu_phi(ce) enddo; enddo; enddo K_ref = K_ref*wgt call MPI_Allreduce(MPI_IN_PLACE,K_ref,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 478efad53..9fe78dd77 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -161,18 +161,16 @@ module homogenization real(pReal) :: f_T end function homogenization_f_T - module function damage_nonlocal_getMobility(ce) result(M) + module function homogenization_mu_phi(ce) result(M) integer, intent(in) :: ce real(pReal) :: M - end function damage_nonlocal_getMobility + end function homogenization_mu_phi - module subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, phi, ce) + module function homogenization_f_phi(phi,ce) result(f_phi) integer, intent(in) :: ce - real(pReal), intent(in) :: & - phi - real(pReal), intent(out) :: & - phiDot - end subroutine damage_nonlocal_getSourceAndItsTangent + real(pReal), intent(in) :: phi + real(pReal) :: f_phi + end function homogenization_f_phi module subroutine homogenization_set_phi(phi,ce) integer, intent(in) :: ce @@ -188,8 +186,8 @@ module homogenization homogenization_thermal_mu_T, & homogenization_K, & homogenization_f_T, & - damage_nonlocal_getMobility, & - damage_nonlocal_getSourceAndItsTangent, & + homogenization_mu_phi, & + homogenization_f_phi, & homogenization_set_phi, & homogenization_thermal_setfield, & homogenization_T, & @@ -201,7 +199,7 @@ module homogenization DAMAGE_NONLOCAL_ID public :: & - damage_nonlocal_getDiffusion + homogenization_K_phi contains @@ -448,27 +446,27 @@ end subroutine homogenization_restartRead !-------------------------------------------------------------------------------------------------- !> @brief returns homogenized non local damage diffusion tensor in reference configuration !-------------------------------------------------------------------------------------------------- -function damage_nonlocal_getDiffusion(ce) +function homogenization_K_phi(ce) integer, intent(in) :: ce real(pReal), dimension(3,3) :: & - damage_nonlocal_getDiffusion + homogenization_K_phi integer :: & ho, & co ho = material_homogenizationID(ce) - damage_nonlocal_getDiffusion = 0.0_pReal + homogenization_K_phi = 0.0_pReal do co = 1, homogenization_Nconstituents(ho) - damage_nonlocal_getDiffusion = damage_nonlocal_getDiffusion + & + homogenization_K_phi = homogenization_K_phi + & crystallite_push33ToRef(co,ce,lattice_D(1:3,1:3,material_phaseID(co,ce))) enddo - damage_nonlocal_getDiffusion = & - num_damage%charLength**2*damage_nonlocal_getDiffusion/real(homogenization_Nconstituents(ho),pReal) + homogenization_K_phi = & + num_damage%charLength**2*homogenization_K_phi/real(homogenization_Nconstituents(ho),pReal) -end function damage_nonlocal_getDiffusion +end function homogenization_K_phi !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index a067dde43..19a5b0f83 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -100,7 +100,7 @@ module subroutine damage_partition(ce) if(damageState_h(material_homogenizationID(ce))%sizeState < 1) return phi = damagestate_h(material_homogenizationID(ce))%state(1,material_homogenizationEntry(ce)) - call phase_damage_set_phi(phi,1,ce) + call phase_set_phi(phi,1,ce) end subroutine damage_partition @@ -109,30 +109,29 @@ end subroutine damage_partition !-------------------------------------------------------------------------------------------------- !> @brief Returns homogenized nonlocal damage mobility !-------------------------------------------------------------------------------------------------- -module function damage_nonlocal_getMobility(ce) result(M) +module function homogenization_mu_phi(ce) result(M) integer, intent(in) :: ce real(pReal) :: M M = lattice_M(material_phaseID(1,ce)) -end function damage_nonlocal_getMobility +end function homogenization_mu_phi !-------------------------------------------------------------------------------------------------- !> @brief calculates homogenized damage driving forces !-------------------------------------------------------------------------------------------------- -module subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, phi, ce) +module function homogenization_f_phi(phi,ce) result(f_phi) integer, intent(in) :: ce real(pReal), intent(in) :: & phi - real(pReal), intent(out) :: & - phiDot + real(pReal) :: f_phi - phiDot = phase_damage_phi_dot(phi, 1, ce) + f_phi = phase_f_phi(phi, 1, ce) -end subroutine damage_nonlocal_getSourceAndItsTangent +end function homogenization_f_phi !-------------------------------------------------------------------------------------------------- diff --git a/src/phase.f90 b/src/phase.f90 index dce63a5ac..57c83c4b4 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -145,26 +145,22 @@ module phase real(pReal), dimension(3,3) :: L_p end function mechanical_L_p - module function phase_F(co,ce) result(F) - integer, intent(in) :: co, ce - real(pReal), dimension(3,3) :: F - end function phase_F - module function mechanical_F_e(ph,me) result(F_e) integer, intent(in) :: ph,me real(pReal), dimension(3,3) :: F_e end function mechanical_F_e + + module function phase_F(co,ce) result(F) + integer, intent(in) :: co, ce + real(pReal), dimension(3,3) :: F + end function phase_F + module function phase_P(co,ce) result(P) integer, intent(in) :: co, ce real(pReal), dimension(3,3) :: P end function phase_P - module function phase_damage_get_phi(co,ip,el) result(phi) - integer, intent(in) :: co, ip, el - real(pReal) :: phi - end function phase_damage_get_phi - module function thermal_T(ph,me) result(T) integer, intent(in) :: ph,me real(pReal) :: T @@ -191,10 +187,10 @@ module phase integer, intent(in) :: ce, co end subroutine phase_thermal_setField - module subroutine phase_damage_set_phi(phi,co,ce) + module subroutine phase_set_phi(phi,co,ce) real(pReal), intent(in) :: phi integer, intent(in) :: co, ce - end subroutine phase_damage_set_phi + end subroutine phase_set_phi ! == cleaned:end =================================================================================== @@ -227,13 +223,13 @@ module phase end function phase_homogenizedC - module function phase_damage_phi_dot(phi,co,ce) result(phi_dot) + module function phase_f_phi(phi,co,ce) result(phi_dot) integer, intent(in) :: ce,co real(pReal), intent(in) :: & phi !< damage parameter real(pReal) :: & phi_dot - end function phase_damage_phi_dot + end function phase_f_phi module function phase_f_T(ph,me) result(f_T) integer, intent(in) :: ph, me @@ -299,7 +295,7 @@ module phase public :: & phase_init, & phase_homogenizedC, & - phase_damage_phi_dot, & + phase_f_phi, & phase_f_T, & phase_results, & phase_allocateState, & @@ -317,8 +313,7 @@ module phase phase_restartRead, & integrateDamageState, & phase_thermal_setField, & - phase_damage_set_phi, & - phase_damage_get_phi, & + phase_set_phi, & phase_P, & phase_set_F, & phase_F diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index 62ce70368..a6d97032f 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -142,7 +142,7 @@ end subroutine damage_init !---------------------------------------------------------------------------------------------- !< @brief returns local part of nonlocal damage driving force !---------------------------------------------------------------------------------------------- -module function phase_damage_phi_dot(phi,co,ce) result(phi_dot) +module function phase_f_phi(phi,co,ce) result(phi_dot) integer, intent(in) :: ce,co real(pReal), intent(in) :: & @@ -165,7 +165,7 @@ module function phase_damage_phi_dot(phi,co,ce) result(phi_dot) phi_dot = 0.0_pReal end select -end function phase_damage_phi_dot +end function phase_f_phi @@ -411,7 +411,7 @@ end function source_active !---------------------------------------------------------------------------------------------- !< @brief Set damage parameter !---------------------------------------------------------------------------------------------- -module subroutine phase_damage_set_phi(phi,co,ce) +module subroutine phase_set_phi(phi,co,ce) real(pReal), intent(in) :: phi integer, intent(in) :: ce, co @@ -419,17 +419,7 @@ module subroutine phase_damage_set_phi(phi,co,ce) current(material_phaseID(co,ce))%phi(material_phaseEntry(co,ce)) = phi -end subroutine phase_damage_set_phi - - -module function phase_damage_get_phi(co,ip,el) result(phi) - - integer, intent(in) :: co, ip, el - real(pReal) :: phi - - phi = current(material_phaseAt(co,el))%phi(material_phaseMemberAt(co,ip,el)) - -end function phase_damage_get_phi +end subroutine phase_set_phi module function damage_phi(ph,me) result(phi) From 00aed99419fdabf792d324f2686c13fdd646e40e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 8 Apr 2021 13:39:48 +0200 Subject: [PATCH 147/219] naming of tests should follow naming in class --- .../test_read[0].pbz2 => get/test_get[0].pbz2} | Bin .../test_read[1].pbz2 => get/test_get[1].pbz2} | Bin .../test_read[2].pbz2 => get/test_get[2].pbz2} | Bin .../test_read[3].pbz2 => get/test_get[3].pbz2} | Bin .../test_read[4].pbz2 => get/test_get[4].pbz2} | Bin .../test_read[5].pbz2 => get/test_get[5].pbz2} | Bin .../test_read[6].pbz2 => get/test_get[6].pbz2} | Bin .../test_read[7].pbz2 => get/test_get[7].pbz2} | Bin python/tests/test_Result.py | 16 ++++++++-------- 9 files changed, 8 insertions(+), 8 deletions(-) rename python/tests/reference/Result/{read/test_read[0].pbz2 => get/test_get[0].pbz2} (100%) rename python/tests/reference/Result/{read/test_read[1].pbz2 => get/test_get[1].pbz2} (100%) rename python/tests/reference/Result/{read/test_read[2].pbz2 => get/test_get[2].pbz2} (100%) rename python/tests/reference/Result/{read/test_read[3].pbz2 => get/test_get[3].pbz2} (100%) rename python/tests/reference/Result/{read/test_read[4].pbz2 => get/test_get[4].pbz2} (100%) rename python/tests/reference/Result/{read/test_read[5].pbz2 => get/test_get[5].pbz2} (100%) rename python/tests/reference/Result/{read/test_read[6].pbz2 => get/test_get[6].pbz2} (100%) rename python/tests/reference/Result/{read/test_read[7].pbz2 => get/test_get[7].pbz2} (100%) diff --git a/python/tests/reference/Result/read/test_read[0].pbz2 b/python/tests/reference/Result/get/test_get[0].pbz2 similarity index 100% rename from python/tests/reference/Result/read/test_read[0].pbz2 rename to python/tests/reference/Result/get/test_get[0].pbz2 diff --git a/python/tests/reference/Result/read/test_read[1].pbz2 b/python/tests/reference/Result/get/test_get[1].pbz2 similarity index 100% rename from python/tests/reference/Result/read/test_read[1].pbz2 rename to python/tests/reference/Result/get/test_get[1].pbz2 diff --git a/python/tests/reference/Result/read/test_read[2].pbz2 b/python/tests/reference/Result/get/test_get[2].pbz2 similarity index 100% rename from python/tests/reference/Result/read/test_read[2].pbz2 rename to python/tests/reference/Result/get/test_get[2].pbz2 diff --git a/python/tests/reference/Result/read/test_read[3].pbz2 b/python/tests/reference/Result/get/test_get[3].pbz2 similarity index 100% rename from python/tests/reference/Result/read/test_read[3].pbz2 rename to python/tests/reference/Result/get/test_get[3].pbz2 diff --git a/python/tests/reference/Result/read/test_read[4].pbz2 b/python/tests/reference/Result/get/test_get[4].pbz2 similarity index 100% rename from python/tests/reference/Result/read/test_read[4].pbz2 rename to python/tests/reference/Result/get/test_get[4].pbz2 diff --git a/python/tests/reference/Result/read/test_read[5].pbz2 b/python/tests/reference/Result/get/test_get[5].pbz2 similarity index 100% rename from python/tests/reference/Result/read/test_read[5].pbz2 rename to python/tests/reference/Result/get/test_get[5].pbz2 diff --git a/python/tests/reference/Result/read/test_read[6].pbz2 b/python/tests/reference/Result/get/test_get[6].pbz2 similarity index 100% rename from python/tests/reference/Result/read/test_read[6].pbz2 rename to python/tests/reference/Result/get/test_get[6].pbz2 diff --git a/python/tests/reference/Result/read/test_read[7].pbz2 b/python/tests/reference/Result/get/test_get[7].pbz2 similarity index 100% rename from python/tests/reference/Result/read/test_read[7].pbz2 rename to python/tests/reference/Result/get/test_get[7].pbz2 diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 63852efc5..a659ce056 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -358,7 +358,7 @@ class TestResult: with pytest.raises(TypeError): default.save_XDMF() - @pytest.mark.parametrize('view,output,compress,strip', + @pytest.mark.parametrize('view,output,flatten,prune', [({},['F','P','F','L_p','F_e','F_p'],True,True), ({'increments':3},'F',True,True), ({'increments':[1,8,3,4,5,6,7]},['F','P'],True,True), @@ -368,22 +368,22 @@ class TestResult: ({'phases':False},['Delta_V'],True,True), ({},['u_p','u_n'],False,False)], ids=list(range(8))) - def test_read(self,update,request,ref_path,view,output,compress,strip): + def test_get(self,update,request,ref_path,view,output,flatten,prune): result = Result(ref_path/'4grains2x4x3_compressionY.hdf5') for key,value in view.items(): result = result.view(key,value) fname = request.node.name - cur = result.get(output,compress,strip) + cur = result.get(output,flatten,prune) if update: - with bz2.BZ2File((ref_path/'read'/fname).with_suffix('.pbz2'),'w') as f: + with bz2.BZ2File((ref_path/'get'/fname).with_suffix('.pbz2'),'w') as f: pickle.dump(cur,f) - with bz2.BZ2File((ref_path/'read'/fname).with_suffix('.pbz2')) as f: + with bz2.BZ2File((ref_path/'get'/fname).with_suffix('.pbz2')) as f: assert dict_equal(cur,pickle.load(f)) - @pytest.mark.parametrize('view,output,compress,constituents,strip', + @pytest.mark.parametrize('view,output,flatten,constituents,prune', [({},['F','P','F','L_p','F_e','F_p'],True,True,None), ({'increments':3},'F',True,True,[0,1,2,3,4,5,6,7]), ({'increments':[1,8,3,4,5,6,7]},['F','P'],True,True,1), @@ -393,13 +393,13 @@ class TestResult: ({'phases':False},['Delta_V'],True,True,[1,2,4]), ({},['u_p','u_n'],False,False,None)], ids=list(range(8))) - def test_place(self,update,request,ref_path,view,output,compress,strip,constituents): + def test_place(self,update,request,ref_path,view,output,flatten,prune,constituents): result = Result(ref_path/'4grains2x4x3_compressionY.hdf5') for key,value in view.items(): result = result.view(key,value) fname = request.node.name - cur = result.place(output,compress,strip,constituents) + cur = result.place(output,flatten,prune,constituents) if update: with bz2.BZ2File((ref_path/'place'/fname).with_suffix('.pbz2'),'w') as f: pickle.dump(cur,f) From 2d8658822dd28e4135feba4c7a472b1f0db08d1a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 8 Apr 2021 14:58:22 +0200 Subject: [PATCH 148/219] report return value --- python/damask/_result.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/python/damask/_result.py b/python/damask/_result.py index 4856a17fa..bf1b17876 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1300,6 +1300,11 @@ class Result: Fill value for non-existent entries of integer type. Defaults to 0. + Returns + ------- + data : dict of numpy.ma.MaskedArray + Datasets structured by spatial position and according to selected view. + """ r = {} From e89236b14d198dcbddc3f55b8fa13f319600ea64 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 8 Apr 2021 17:36:33 +0200 Subject: [PATCH 149/219] bugfix: don't overwrite data when doing a 'place-like' operation to merge datasets --- python/damask/_result.py | 2 +- python/tests/reference/Result/save_VTK/test_vtk[0-0-0].md5 | 2 +- python/tests/reference/Result/save_VTK/test_vtk[0-0-1].md5 | 2 +- python/tests/reference/Result/save_VTK/test_vtk[0-0-2].md5 | 2 +- python/tests/reference/Result/save_VTK/test_vtk[1-0-0].md5 | 2 +- python/tests/reference/Result/save_VTK/test_vtk[1-0-1].md5 | 2 +- python/tests/reference/Result/save_VTK/test_vtk[1-0-2].md5 | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index bf1b17876..89c704b94 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1195,9 +1195,9 @@ class Result: for ty in ['phase','homogenization']: for field in self.visible['fields']: + outs = {} for label in self.visible[ty+'s']: if field not in f['/'.join([inc,ty,label])].keys(): continue - outs = {} for out in _match(output,f['/'.join([inc,ty,label,field])].keys()): data = ma.array(_read(f['/'.join([inc,ty,label,field,out])])) diff --git a/python/tests/reference/Result/save_VTK/test_vtk[0-0-0].md5 b/python/tests/reference/Result/save_VTK/test_vtk[0-0-0].md5 index c7fe1c66e..838037bb2 100644 --- a/python/tests/reference/Result/save_VTK/test_vtk[0-0-0].md5 +++ b/python/tests/reference/Result/save_VTK/test_vtk[0-0-0].md5 @@ -1 +1 @@ -4ab2840cc5ba8d0b17a6fffb014b31a8 \ No newline at end of file +3b83384def67552ab7dd211efc0d54fd \ No newline at end of file diff --git a/python/tests/reference/Result/save_VTK/test_vtk[0-0-1].md5 b/python/tests/reference/Result/save_VTK/test_vtk[0-0-1].md5 index e4af3f438..7ceffc337 100644 --- a/python/tests/reference/Result/save_VTK/test_vtk[0-0-1].md5 +++ b/python/tests/reference/Result/save_VTK/test_vtk[0-0-1].md5 @@ -1 +1 @@ -ff0f4079c18fcbb05fd08cf788230183 \ No newline at end of file +c32c86ed50dbb39a93ca2a2ebe47d9cb \ No newline at end of file diff --git a/python/tests/reference/Result/save_VTK/test_vtk[0-0-2].md5 b/python/tests/reference/Result/save_VTK/test_vtk[0-0-2].md5 index 678cbf390..f5b7daec3 100644 --- a/python/tests/reference/Result/save_VTK/test_vtk[0-0-2].md5 +++ b/python/tests/reference/Result/save_VTK/test_vtk[0-0-2].md5 @@ -1 +1 @@ -3e72bea74635365e78a703254107ee07 \ No newline at end of file +ead4f6fcaff174fddc041d701e54ac60 \ No newline at end of file diff --git a/python/tests/reference/Result/save_VTK/test_vtk[1-0-0].md5 b/python/tests/reference/Result/save_VTK/test_vtk[1-0-0].md5 index 974866e6d..df00a513f 100644 --- a/python/tests/reference/Result/save_VTK/test_vtk[1-0-0].md5 +++ b/python/tests/reference/Result/save_VTK/test_vtk[1-0-0].md5 @@ -1 +1 @@ -947f5fe28599a16cfb444b7371df2cae \ No newline at end of file +bde8b728110c2c05a6a4740f7c5f9c06 \ No newline at end of file diff --git a/python/tests/reference/Result/save_VTK/test_vtk[1-0-1].md5 b/python/tests/reference/Result/save_VTK/test_vtk[1-0-1].md5 index 0e9c5eb35..35c577900 100644 --- a/python/tests/reference/Result/save_VTK/test_vtk[1-0-1].md5 +++ b/python/tests/reference/Result/save_VTK/test_vtk[1-0-1].md5 @@ -1 +1 @@ -76f4147d98999f131272a1d762fcf93c \ No newline at end of file +e09bfa9248283fc390003ad28d15d36e \ No newline at end of file diff --git a/python/tests/reference/Result/save_VTK/test_vtk[1-0-2].md5 b/python/tests/reference/Result/save_VTK/test_vtk[1-0-2].md5 index d3c633430..d5874d88b 100644 --- a/python/tests/reference/Result/save_VTK/test_vtk[1-0-2].md5 +++ b/python/tests/reference/Result/save_VTK/test_vtk[1-0-2].md5 @@ -1 +1 @@ -e76b8ecc66a516eccd6b3e15fc8adc66 \ No newline at end of file +3f21254164f96de8ee4a28249ae72cc6 \ No newline at end of file From 1b89032086e1b41090b2c5a45fcaf81714810637 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 8 Apr 2021 23:40:20 +0200 Subject: [PATCH 150/219] names as in DAMASK paper --- src/grid/grid_thermal_spectral.f90 | 8 ++++---- src/homogenization.f90 | 30 ++++++++++++++---------------- src/homogenization_damage.f90 | 12 ++++++------ src/homogenization_thermal.f90 | 22 +++++++++++----------- src/phase.f90 | 8 ++++---- src/phase_damage.f90 | 10 +++++----- src/phase_thermal.f90 | 10 +++++----- 7 files changed, 49 insertions(+), 51 deletions(-) diff --git a/src/grid/grid_thermal_spectral.f90 b/src/grid/grid_thermal_spectral.f90 index 7d4878b12..ea6caec0e 100644 --- a/src/grid/grid_thermal_spectral.f90 +++ b/src/grid/grid_thermal_spectral.f90 @@ -270,7 +270,7 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) ce = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - vectorField_real(1:3,i,j,k) = matmul(homogenization_K(ce) - K_ref, & + vectorField_real(1:3,i,j,k) = matmul(homogenization_K_T(ce) - K_ref, & vectorField_real(1:3,i,j,k)) enddo; enddo; enddo call utilities_FFTvectorForward @@ -280,7 +280,7 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 scalarField_real(i,j,k) = params%timeinc*(scalarField_real(i,j,k) + homogenization_f_T(ce)) & - + homogenization_thermal_mu_T(ce) * (T_lastInc(i,j,k) - T_current(i,j,k)) & + + homogenization_mu_T(ce) * (T_lastInc(i,j,k) - T_current(i,j,k)) & + mu_ref*T_current(i,j,k) enddo; enddo; enddo @@ -309,8 +309,8 @@ subroutine updateReference mu_ref = 0.0_pReal do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - K_ref = K_ref + homogenization_K(ce) - mu_ref = mu_ref + homogenization_thermal_mu_T(ce) + K_ref = K_ref + homogenization_K_T(ce) + mu_ref = mu_ref + homogenization_mu_T(ce) enddo; enddo; enddo K_ref = K_ref*wgt call MPI_Allreduce(MPI_IN_PLACE,K_ref,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 9fe78dd77..34e71a0f2 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -136,15 +136,15 @@ module homogenization end function mechanical_updateState - module function homogenization_K(ce) result(K) + module function homogenization_K_T(ce) result(K) integer, intent(in) :: ce real(pReal), dimension(3,3) :: K - end function homogenization_K + end function homogenization_K_T - module function homogenization_thermal_mu_T(ce) result(mu_T) + module function homogenization_mu_T(ce) result(mu) integer, intent(in) :: ce - real(pReal) :: mu_T - end function homogenization_thermal_mu_T + real(pReal) :: mu + end function homogenization_mu_T module subroutine homogenization_thermal_setField(T,dot_T, ce) integer, intent(in) :: ce @@ -156,20 +156,20 @@ module homogenization real(pReal) :: T end function homogenization_T - module function homogenization_f_T(ce) result(f_T) + module function homogenization_f_T(ce) result(f) integer, intent(in) :: ce - real(pReal) :: f_T + real(pReal) :: f end function homogenization_f_T - module function homogenization_mu_phi(ce) result(M) + module function homogenization_mu_phi(ce) result(mu) integer, intent(in) :: ce - real(pReal) :: M + real(pReal) :: mu end function homogenization_mu_phi - module function homogenization_f_phi(phi,ce) result(f_phi) + module function homogenization_f_phi(phi,ce) result(f) integer, intent(in) :: ce real(pReal), intent(in) :: phi - real(pReal) :: f_phi + real(pReal) :: f end function homogenization_f_phi module subroutine homogenization_set_phi(phi,ce) @@ -183,9 +183,10 @@ module homogenization public :: & homogenization_init, & materialpoint_stressAndItsTangent, & - homogenization_thermal_mu_T, & - homogenization_K, & + homogenization_mu_T, & + homogenization_K_T, & homogenization_f_T, & + homogenization_K_phi, & homogenization_mu_phi, & homogenization_f_phi, & homogenization_set_phi, & @@ -198,9 +199,6 @@ module homogenization THERMAL_CONDUCTION_ID, & DAMAGE_NONLOCAL_ID - public :: & - homogenization_K_phi - contains diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index 19a5b0f83..f0f13bdbb 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -109,12 +109,12 @@ end subroutine damage_partition !-------------------------------------------------------------------------------------------------- !> @brief Returns homogenized nonlocal damage mobility !-------------------------------------------------------------------------------------------------- -module function homogenization_mu_phi(ce) result(M) +module function homogenization_mu_phi(ce) result(mu) integer, intent(in) :: ce - real(pReal) :: M + real(pReal) :: mu - M = lattice_M(material_phaseID(1,ce)) + mu = lattice_M(material_phaseID(1,ce)) end function homogenization_mu_phi @@ -122,14 +122,14 @@ end function homogenization_mu_phi !-------------------------------------------------------------------------------------------------- !> @brief calculates homogenized damage driving forces !-------------------------------------------------------------------------------------------------- -module function homogenization_f_phi(phi,ce) result(f_phi) +module function homogenization_f_phi(phi,ce) result(f) integer, intent(in) :: ce real(pReal), intent(in) :: & phi - real(pReal) :: f_phi + real(pReal) :: f - f_phi = phase_f_phi(phi, 1, ce) + f = phase_f_phi(phi, 1, ce) end function homogenization_f_phi diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index a372a7494..8b4eafc3a 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -109,7 +109,7 @@ end subroutine thermal_homogenize !-------------------------------------------------------------------------------------------------- !> @brief return homogenized thermal conductivity in reference configuration !-------------------------------------------------------------------------------------------------- -module function homogenization_K(ce) result(K) +module function homogenization_K_T(ce) result(K) integer, intent(in) :: ce real(pReal), dimension(3,3) :: K @@ -125,17 +125,17 @@ module function homogenization_K(ce) result(K) K = K / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) -end function homogenization_K +end function homogenization_K_T -module function homogenization_thermal_mu_T(ce) result(mu_T) +module function homogenization_mu_T(ce) result(mu) integer, intent(in) :: ce - real(pReal) :: mu_T + real(pReal) :: mu - mu_T = c_P(ce) * rho(ce) + mu = c_P(ce) * rho(ce) -end function homogenization_thermal_mu_T +end function homogenization_mu_T !-------------------------------------------------------------------------------------------------- @@ -234,19 +234,19 @@ end function homogenization_T !-------------------------------------------------------------------------------------------------- !> @brief return heat generation rate !-------------------------------------------------------------------------------------------------- -module function homogenization_f_T(ce) result(f_T) +module function homogenization_f_T(ce) result(f) integer, intent(in) :: ce - real(pReal) :: f_T + real(pReal) :: f integer :: co - f_T = phase_f_T(material_phaseID(1,ce),material_phaseEntry(1,ce)) + f = phase_f_T(material_phaseID(1,ce),material_phaseEntry(1,ce)) do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) - f_T = f_T + phase_f_T(material_phaseID(co,ce),material_phaseEntry(co,ce)) + f = f + phase_f_T(material_phaseID(co,ce),material_phaseEntry(co,ce)) enddo - f_T = f_T/real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) + f = f/real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) end function homogenization_f_T diff --git a/src/phase.f90 b/src/phase.f90 index 57c83c4b4..346772ce4 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -223,17 +223,17 @@ module phase end function phase_homogenizedC - module function phase_f_phi(phi,co,ce) result(phi_dot) + module function phase_f_phi(phi,co,ce) result(f) integer, intent(in) :: ce,co real(pReal), intent(in) :: & phi !< damage parameter real(pReal) :: & - phi_dot + f end function phase_f_phi - module function phase_f_T(ph,me) result(f_T) + module function phase_f_T(ph,me) result(f) integer, intent(in) :: ph, me - real(pReal) :: f_T + real(pReal) :: f end function phase_f_T module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,i,e) diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index a6d97032f..189a5eabf 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -142,13 +142,13 @@ end subroutine damage_init !---------------------------------------------------------------------------------------------- !< @brief returns local part of nonlocal damage driving force !---------------------------------------------------------------------------------------------- -module function phase_f_phi(phi,co,ce) result(phi_dot) +module function phase_f_phi(phi,co,ce) result(f) integer, intent(in) :: ce,co real(pReal), intent(in) :: & phi !< damage parameter real(pReal) :: & - phi_dot + f integer :: & ph, & @@ -159,10 +159,10 @@ module function phase_f_phi(phi,co,ce) result(phi_dot) select case(phase_source(ph)) case(DAMAGE_ISOBRITTLE_ID,DAMAGE_ISODUCTILE_ID,DAMAGE_ANISOBRITTLE_ID,DAMAGE_ANISODUCTILE_ID) - phi_dot = 1.0_pReal & - - phi*damageState(ph)%state(1,en) + f = 1.0_pReal & + - phi*damageState(ph)%state(1,en) case default - phi_dot = 0.0_pReal + f = 0.0_pReal end select end function phase_f_phi diff --git a/src/phase_thermal.f90 b/src/phase_thermal.f90 index e7f9abdc5..807e1f655 100644 --- a/src/phase_thermal.f90 +++ b/src/phase_thermal.f90 @@ -121,25 +121,25 @@ end subroutine thermal_init !---------------------------------------------------------------------------------------------- !< @brief calculates thermal dissipation rate !---------------------------------------------------------------------------------------------- -module function phase_f_T(ph,me) result(f_T) +module function phase_f_T(ph,me) result(f) integer, intent(in) :: ph, me - real(pReal) :: f_T + real(pReal) :: f integer :: so - f_T = 0.0_pReal + f = 0.0_pReal do so = 1, thermal_Nsources(ph) select case(thermal_source(so,ph)) case (THERMAL_DISSIPATION_ID) - f_T = f_T + dissipation_f_T(ph,me) + f = f + dissipation_f_T(ph,me) case (THERMAL_EXTERNALHEAT_ID) - f_T = f_T + externalheat_f_T(ph,me) + f = f + externalheat_f_T(ph,me) end select From 5f608ed572d33122f21c7dd3f0c2e27e6429f904 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 9 Apr 2021 08:25:30 +0200 Subject: [PATCH 151/219] only 2 and 3 dimension can be 1 --- src/grid/discretization_grid.f90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/grid/discretization_grid.f90 b/src/grid/discretization_grid.f90 index bb6fa9d8d..88216f0aa 100644 --- a/src/grid/discretization_grid.f90 +++ b/src/grid/discretization_grid.f90 @@ -74,6 +74,8 @@ subroutine discretization_grid_init(restart) allocate(materialAt_global(0)) ! needed for IntelMPI endif + if (grid(1) < 2) call IO_error(844, ext_msg='cells(1) must be larger than 1') + call MPI_Bcast(grid,3,MPI_INTEGER,0,PETSC_COMM_WORLD, ierr) if (ierr /= 0) error stop 'MPI error' call MPI_Bcast(geomSize,3,MPI_DOUBLE,0,PETSC_COMM_WORLD, ierr) From 551b57015f409edaa2184e7e6e810c176c9a2c5b Mon Sep 17 00:00:00 2001 From: Test User Date: Fri, 9 Apr 2021 13:46:38 +0200 Subject: [PATCH 152/219] [skip ci] updated version information after successful test of v3.0.0-alpha2-780-ga164a980e --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index a4ae6ed29..523b2519b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-767-g3c967abcd +v3.0.0-alpha2-780-ga164a980e From c00b29097148f84388af2b0c7e036fce7736c793 Mon Sep 17 00:00:00 2001 From: Test User Date: Sat, 10 Apr 2021 02:32:18 +0200 Subject: [PATCH 153/219] [skip ci] updated version information after successful test of v3.0.0-alpha2-829-g73b07eda4 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 523b2519b..6855a7dca 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-780-ga164a980e +v3.0.0-alpha2-829-g73b07eda4 From 44331c504b0394ee465aff7e23a91c564e81a120 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 10 Apr 2021 08:29:42 +0200 Subject: [PATCH 154/219] __class__ is unknown (says prospector) --- python/damask/_orientation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 5875f1d1c..5cc412c98 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -238,7 +238,7 @@ class Orientation(Rotation): """ matching_type = all([hasattr(other,attr) and getattr(self,attr) == getattr(other,attr) for attr in ['family','lattice','parameters']]) - return np.logical_and(super(__class__,self.reduced).__eq__(other.reduced),matching_type) + return np.logical_and(matching_type,super(self.__class__,self.reduced).__eq__(other.reduced)) def __ne__(self,other): """ @@ -276,7 +276,7 @@ class Orientation(Rotation): """ matching_type = all([hasattr(other,attr) and getattr(self,attr) == getattr(other,attr) for attr in ['family','lattice','parameters']]) - return np.logical_and(super(__class__,self.reduced).isclose(other.reduced),matching_type) + return np.logical_and(matching_type,super(self.__class__,self.reduced).isclose(other.reduced)) From 07d573a56dd3fa5e2c72e0f07996b1df044f642c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 10 Apr 2021 09:32:21 +0200 Subject: [PATCH 155/219] more helpful dataset descriptors phase label for single phase material not helpful --- python/damask/_result.py | 5 +- .../6grains6x7x8_single_phase_tensionY.xdmf | 1036 ++++++++--------- 2 files changed, 521 insertions(+), 520 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 89c704b94..8196169f4 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1044,7 +1044,8 @@ class Result: collection = ET.SubElement(domain, 'Grid') collection.attrib={'GridType': 'Collection', - 'CollectionType': 'Temporal'} + 'CollectionType': 'Temporal', + 'Name': 'Increments'} time = ET.SubElement(collection, 'Time') time.attrib={'TimeType': 'List'} @@ -1106,7 +1107,7 @@ class Result: unit = f[name].attrs[u] if h5py3 else f[name].attrs[u].decode() attributes.append(ET.SubElement(grid, 'Attribute')) - attributes[-1].attrib = {'Name': name.split('/',2)[2]+f' / {unit}', + attributes[-1].attrib = {'Name': '/'.join([ty,field,out])+f' / {unit}', 'Center': 'Cell', 'AttributeType': attribute_type_map[shape]} data_items.append(ET.SubElement(attributes[-1], 'DataItem')) diff --git a/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.xdmf b/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.xdmf index 31d9d0924..87352e5f9 100644 --- a/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.xdmf +++ b/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.xdmf @@ -1,7 +1,7 @@ - + @@ -14,145 +14,145 @@ 6grains6x7x8_single_phase_tensionY.hdf5:/increment_0/geometry/u_n - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/F - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/F_e - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/F_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/L_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/O - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/P - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/xi_sl @@ -165,145 +165,145 @@ 6grains6x7x8_single_phase_tensionY.hdf5:/increment_4/geometry/u_n - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/F - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/F_e - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/F_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/L_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/O - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/P - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/xi_sl @@ -316,145 +316,145 @@ 6grains6x7x8_single_phase_tensionY.hdf5:/increment_8/geometry/u_n - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/F - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/F_e - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/F_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/L_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/O - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/P - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/xi_sl @@ -467,145 +467,145 @@ 6grains6x7x8_single_phase_tensionY.hdf5:/increment_12/geometry/u_n - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/F - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/F_e - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/F_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/L_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/O - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/P - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/xi_sl @@ -618,145 +618,145 @@ 6grains6x7x8_single_phase_tensionY.hdf5:/increment_16/geometry/u_n - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/F - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/F_e - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/F_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/L_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/O - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/P - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/xi_sl @@ -769,145 +769,145 @@ 6grains6x7x8_single_phase_tensionY.hdf5:/increment_20/geometry/u_n - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/F - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/F_e - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/F_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/L_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/O - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/P - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/xi_sl @@ -920,145 +920,145 @@ 6grains6x7x8_single_phase_tensionY.hdf5:/increment_24/geometry/u_n - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/F - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/F_e - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/F_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/L_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/O - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/P - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/xi_sl @@ -1071,145 +1071,145 @@ 6grains6x7x8_single_phase_tensionY.hdf5:/increment_28/geometry/u_n - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/F - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/F_e - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/F_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/L_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/O - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/P - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/xi_sl @@ -1222,145 +1222,145 @@ 6grains6x7x8_single_phase_tensionY.hdf5:/increment_32/geometry/u_n - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/F - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/F_e - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/F_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/L_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/O - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/P - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/xi_sl @@ -1373,145 +1373,145 @@ 6grains6x7x8_single_phase_tensionY.hdf5:/increment_36/geometry/u_n - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/F - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/F_e - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/F_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/L_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/O - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/P - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/xi_sl @@ -1524,145 +1524,145 @@ 6grains6x7x8_single_phase_tensionY.hdf5:/increment_40/geometry/u_n - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/F - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/F_e - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/F_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/L_p - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/O - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/P - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_f4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_f8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_i1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_i2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_i4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_i8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_u1 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_u2 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_u4 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_u8 - + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/xi_sl From d304654972415612582e9c754fe19126ca8c5348 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 10 Apr 2021 09:33:45 +0200 Subject: [PATCH 156/219] allow easy detection of empty view/get/place --- python/damask/_result.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 8196169f4..667a89c87 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1266,7 +1266,7 @@ class Result: if prune: r = util.dict_prune(r) if flatten: r = util.dict_flatten(r) - return r + return None if (type(r) == dict and r == {}) else r def place(self,output='*',flatten=True,prune=True,constituents=None,fill_float=np.nan,fill_int=0): @@ -1353,4 +1353,4 @@ class Result: if prune: r = util.dict_prune(r) if flatten: r = util.dict_flatten(r) - return r + return None if (type(r) == dict and r == {}) else r From 37df78a8e0510834e43efe877e762754d0c779b6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 10 Apr 2021 09:35:10 +0200 Subject: [PATCH 157/219] don't show progress bar for empty iterations --- python/damask/util.py | 2 +- .../reference/Result/get/test_get[1].pbz2 | Bin 48 -> 46 bytes .../reference/Result/get/test_get[5].pbz2 | Bin 48 -> 46 bytes .../reference/Result/place/test_place[1].pbz2 | Bin 48 -> 46 bytes .../reference/Result/place/test_place[5].pbz2 | Bin 48 -> 46 bytes python/tests/test_Result.py | 33 +++++++++++------- 6 files changed, 21 insertions(+), 14 deletions(-) diff --git a/python/damask/util.py b/python/damask/util.py index 3fe30320a..b519fb15e 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -137,7 +137,7 @@ def show_progress(iterable,N_iter=None,prefix='',bar_length=50): Character length of bar. Defaults to 50. """ - if N_iter == 1 or (hasattr(iterable,'__len__') and len(iterable) == 1): + if N_iter in [0,1] or (hasattr(iterable,'__len__') and len(iterable) <= 1): for item in iterable: yield item else: diff --git a/python/tests/reference/Result/get/test_get[1].pbz2 b/python/tests/reference/Result/get/test_get[1].pbz2 index c1963d4eaf5b3c808081454a4553c95097f00396..088e68f70a76de1221804f0d88b96e86d7953727 100644 GIT binary patch literal 46 zcmZ>Y%CIzaj8qGb6z0;t&cMKU#eoG#GB7$YC@?6_$}sj7w~0L|^3ch_M`L{q0QX`G AhX4Qo literal 48 zcmZ>Y%CIzaj8qGbd?Z-;kb!~m!UGl{$-v~mz`~%wpxD+pi#fQkTqU@blTT56o&W$p C8Vo%E diff --git a/python/tests/reference/Result/get/test_get[5].pbz2 b/python/tests/reference/Result/get/test_get[5].pbz2 index c1963d4eaf5b3c808081454a4553c95097f00396..088e68f70a76de1221804f0d88b96e86d7953727 100644 GIT binary patch literal 46 zcmZ>Y%CIzaj8qGb6z0;t&cMKU#eoG#GB7$YC@?6_$}sj7w~0L|^3ch_M`L{q0QX`G AhX4Qo literal 48 zcmZ>Y%CIzaj8qGbd?Z-;kb!~m!UGl{$-v~mz`~%wpxD+pi#fQkTqU@blTT56o&W$p C8Vo%E diff --git a/python/tests/reference/Result/place/test_place[1].pbz2 b/python/tests/reference/Result/place/test_place[1].pbz2 index c1963d4eaf5b3c808081454a4553c95097f00396..088e68f70a76de1221804f0d88b96e86d7953727 100644 GIT binary patch literal 46 zcmZ>Y%CIzaj8qGb6z0;t&cMKU#eoG#GB7$YC@?6_$}sj7w~0L|^3ch_M`L{q0QX`G AhX4Qo literal 48 zcmZ>Y%CIzaj8qGbd?Z-;kb!~m!UGl{$-v~mz`~%wpxD+pi#fQkTqU@blTT56o&W$p C8Vo%E diff --git a/python/tests/reference/Result/place/test_place[5].pbz2 b/python/tests/reference/Result/place/test_place[5].pbz2 index c1963d4eaf5b3c808081454a4553c95097f00396..088e68f70a76de1221804f0d88b96e86d7953727 100644 GIT binary patch literal 46 zcmZ>Y%CIzaj8qGb6z0;t&cMKU#eoG#GB7$YC@?6_$}sj7w~0L|^3ch_M`L{q0QX`G AhX4Qo literal 48 zcmZ>Y%CIzaj8qGbd?Z-;kb!~m!UGl{$-v~mz`~%wpxD+pi#fQkTqU@blTT56o&W$p C8Vo%E diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index a659ce056..0c34e7989 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -65,14 +65,17 @@ class TestResult: assert dict_equal(a,default.view('times','*').get('F')) assert dict_equal(a,default.view('times',default.times_in_range(0.0,np.inf)).get('F')) - @pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations + @pytest.mark.parametrize('what',['increments','times','phases','fields']) # ToDo: discuss homogenizations def test_view_none(self,default,what): - a = default.view(what,False).get('F') - b = default.view(what,[]).get('F') + n0 = default.view(what,False) + n1 = default.view(what,[]) - assert a == b == {} + label = 'increments' if what == 'times' else what - @pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations + assert n0.get('F') is n1.get('F') is None and \ + len(n0.visible[label]) == len(n1.visible[label]) == 0 + + @pytest.mark.parametrize('what',['increments','times','phases','fields']) # ToDo: discuss homogenizations def test_view_more(self,default,what): empty = default.view(what,False) @@ -81,14 +84,17 @@ class TestResult: assert dict_equal(a,b) - @pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations + @pytest.mark.parametrize('what',['increments','times','phases','fields']) # ToDo: discuss homogenizations def test_view_less(self,default,what): full = default.view(what,True) - a = full.view_less(what,'*').get('F') - b = full.view_less(what,True).get('F') + n0 = full.view_less(what,'*') + n1 = full.view_less(what,True) - assert a == b == {} + label = 'increments' if what == 'times' else what + + assert n0.get('F') is n1.get('F') is None and \ + len(n0.visible[label]) == len(n1.visible[label]) == 0 def test_view_invalid(self,default): with pytest.raises(AttributeError): @@ -189,7 +195,7 @@ class TestResult: default.add_stress_Cauchy('P','F') default.add_calculation('sigma_y','#sigma#',unit='y') default.add_equivalent_Mises('sigma_y') - assert default.get('sigma_y_vM') == {} + assert default.get('sigma_y_vM') is None def test_add_Mises_stress_strain(self,default): default.add_stress_Cauchy('P','F') @@ -380,8 +386,8 @@ class TestResult: pickle.dump(cur,f) with bz2.BZ2File((ref_path/'get'/fname).with_suffix('.pbz2')) as f: - assert dict_equal(cur,pickle.load(f)) - + ref = pickle.load(f) + assert cur is None if ref is None else dict_equal(cur,ref) @pytest.mark.parametrize('view,output,flatten,constituents,prune', [({},['F','P','F','L_p','F_e','F_p'],True,True,None), @@ -405,4 +411,5 @@ class TestResult: pickle.dump(cur,f) with bz2.BZ2File((ref_path/'place'/fname).with_suffix('.pbz2')) as f: - assert dict_equal(cur,pickle.load(f)) + ref = pickle.load(f) + assert cur is None if ref is None else dict_equal(cur,ref) From 4d9949547c43a917688c47cb621e4b968a9b7507 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 10 Apr 2021 20:52:46 +0200 Subject: [PATCH 158/219] more systematic name --- src/CPFEM.f90 | 2 +- src/DAMASK_Marc.f90 | 12 ++++++------ src/Marc/discretization_Marc.f90 | 20 ++++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index 4961b99d4..60dc78d2e 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -156,7 +156,7 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS ODD_JACOBIAN = 1e50_pReal !< return value for jacobian if terminallyIll - elCP = mesh_FEM2DAMASK_elem(elFE) + elCP = discretization_Marc_FEM2DAMASK_elem(elFE) ma = (elCP-1) * discretization_nIPs + ip diff --git a/src/DAMASK_Marc.f90 b/src/DAMASK_Marc.f90 index e417be2fa..a1ce8fa0d 100644 --- a/src/DAMASK_Marc.f90 +++ b/src/DAMASK_Marc.f90 @@ -266,7 +266,7 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, & computationMode = CPFEM_RESTOREJACOBIAN elseif (lovl == 6) then ! stress requested by marc computationMode = CPFEM_CALCRESULTS - cp_en = mesh_FEM2DAMASK_elem(m(1)) + cp_en = discretization_Marc_FEM2DAMASK_elem(m(1)) if (cptim > theTime .or. inc /= theInc) then ! reached "convergence" terminallyIll = .false. cycleCounter = -1 ! first calc step increments this to cycle = 0 @@ -370,11 +370,11 @@ subroutine uedinc(inc,incsub) if (inc > inc_written) then - allocate(d_n(3,count(mesh_FEM2DAMASK_node /= -1))) - do n = lbound(mesh_FEM2DAMASK_node,1), ubound(mesh_FEM2DAMASK_node,1) - if (mesh_FEM2DAMASK_node(n) /= -1) then - call nodvar(1,n,d_n(1:3,mesh_FEM2DAMASK_node(n)),nqncomp,nqdatatype) - if(nqncomp == 2) d_n(3,mesh_FEM2DAMASK_node(n)) = 0.0_pReal + allocate(d_n(3,count(discretization_Marc_FEM2DAMASK_node /= -1))) + do n = lbound(discretization_Marc_FEM2DAMASK_node,1), ubound(discretization_Marc_FEM2DAMASK_node,1) + if (discretization_Marc_FEM2DAMASK_node(n) /= -1) then + call nodvar(1,n,d_n(1:3,discretization_Marc_FEM2DAMASK_node(n)),nqncomp,nqdatatype) + if(nqncomp == 2) d_n(3,discretization_Marc_FEM2DAMASK_node(n)) = 0.0_pReal endif enddo diff --git a/src/Marc/discretization_Marc.f90 b/src/Marc/discretization_Marc.f90 index d92623215..677cf1b52 100644 --- a/src/Marc/discretization_Marc.f90 +++ b/src/Marc/discretization_Marc.f90 @@ -24,8 +24,8 @@ module discretization_marc mesh_unitlength !< physical length of one unit in mesh MD: needs systematic_name integer, dimension(:), allocatable, public, protected :: & - mesh_FEM2DAMASK_elem, & !< DAMASK element ID for Marc element ID MD: Needs systematic name - mesh_FEM2DAMASK_node !< DAMASK node ID for Marc node ID MD: needs systematic_name + discretization_Marc_FEM2DAMASK_elem, & !< DAMASK element ID for Marc element ID + discretization_Marc_FEM2DAMASK_node !< DAMASK node ID for Marc node ID type tCellNodeDefinition @@ -127,7 +127,7 @@ subroutine discretization_marc_UpdateNodeAndIpCoords(d_n) real(pReal), dimension(:,:), allocatable :: node_cell - node_cell = buildCellNodes(discretization_NodeCoords0(1:3,1:maxval(mesh_FEM2DAMASK_node)) + d_n) + node_cell = buildCellNodes(discretization_NodeCoords0(1:3,1:maxval(discretization_Marc_FEM2DAMASK_node)) + d_n) call discretization_setNodeCoords(node_cell) call discretization_setIPcoords(buildIPcoordinates(node_cell)) @@ -219,10 +219,10 @@ subroutine inputRead(elem,node0_elem,connectivity_elem,materialAt) call inputRead_elemType(elem, & nElems,inputFile) - call inputRead_mapElems(mesh_FEM2DAMASK_elem,& + call inputRead_mapElems(discretization_Marc_FEM2DAMASK_elem,& nElems,elem%nNodes,inputFile) - call inputRead_mapNodes(mesh_FEM2DAMASK_node,& + call inputRead_mapNodes(discretization_Marc_FEM2DAMASK_node,& nNodes,inputFile) call inputRead_elemNodes(node0_elem, & @@ -532,7 +532,7 @@ subroutine inputRead_elemNodes(nodes, & if(IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'coordinates') then chunkPos = [4,1,10,11,30,31,50,51,70] do i=1,nNode - m = mesh_FEM2DAMASK_node(IO_intValue(fileContent(l+1+i),chunkPos,1)) + m = discretization_Marc_FEM2DAMASK_node(IO_intValue(fileContent(l+1+i),chunkPos,1)) do j = 1,3 nodes(j,m) = mesh_unitlength * IO_floatValue(fileContent(l+1+i),chunkPos,j+1) enddo @@ -653,11 +653,11 @@ function inputRead_connectivityElem(nElem,nNodes,fileContent) j = 0 do i = 1,nElem chunkPos = IO_stringPos(fileContent(l+1+i+j)) - e = mesh_FEM2DAMASK_elem(IO_intValue(fileContent(l+1+i+j),chunkPos,1)) + e = discretization_Marc_FEM2DAMASK_elem(IO_intValue(fileContent(l+1+i+j),chunkPos,1)) if (e /= 0) then ! disregard non CP elems do k = 1,chunkPos(1)-2 inputRead_connectivityElem(k,e) = & - mesh_FEM2DAMASK_node(IO_IntValue(fileContent(l+1+i+j),chunkPos,k+2)) + discretization_Marc_FEM2DAMASK_node(IO_IntValue(fileContent(l+1+i+j),chunkPos,k+2)) enddo nNodesAlreadyRead = chunkPos(1) - 2 do while(nNodesAlreadyRead < nNodes) ! read on if not all nodes in one line @@ -665,7 +665,7 @@ function inputRead_connectivityElem(nElem,nNodes,fileContent) chunkPos = IO_stringPos(fileContent(l+1+i+j)) do k = 1,chunkPos(1) inputRead_connectivityElem(nNodesAlreadyRead+k,e) = & - mesh_FEM2DAMASK_node(IO_IntValue(fileContent(l+1+i+j),chunkPos,k)) + discretization_Marc_FEM2DAMASK_node(IO_IntValue(fileContent(l+1+i+j),chunkPos,k)) enddo nNodesAlreadyRead = nNodesAlreadyRead + chunkPos(1) enddo @@ -718,7 +718,7 @@ subroutine inputRead_material(materialAt,& if (initialcondTableStyle == 2) m = m + 2 contInts = continuousIntValues(fileContent(l+k+m+1:),nElem,nameElemSet,mapElemSet,size(nameElemSet)) ! get affected elements do i = 1,contInts(1) - e = mesh_FEM2DAMASK_elem(contInts(1+i)) + e = discretization_Marc_FEM2DAMASK_elem(contInts(1+i)) materialAt(e) = myVal enddo if (initialcondTableStyle == 0) m = m + 1 From 690777ac8808a7573b0806b4471c175ccbc02a93 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 10 Apr 2021 21:10:17 +0200 Subject: [PATCH 159/219] base access on cell numbers DAMASK does not care about elem, IP, etc.. --- src/Marc/discretization_Marc.f90 | 36 ++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/Marc/discretization_Marc.f90 b/src/Marc/discretization_Marc.f90 index 677cf1b52..c9f099758 100644 --- a/src/Marc/discretization_Marc.f90 +++ b/src/Marc/discretization_Marc.f90 @@ -39,8 +39,9 @@ module discretization_marc connectivity_cell !< cell connectivity for each element,ip/cell public :: & - discretization_marc_init, & - discretization_marc_UpdateNodeAndIpCoords + discretization_Marc_init, & + discretization_Marc_updateNodeAndIpCoords, & + discretization_Marc_FEM2DAMASK_cell contains @@ -48,7 +49,7 @@ contains !> @brief initializes the mesh by calling all necessary private routines the mesh module !! Order and routines strongly depend on type of solver !-------------------------------------------------------------------------------------------------- -subroutine discretization_marc_init +subroutine discretization_Marc_init real(pReal), dimension(:,:), allocatable :: & node0_elem, & !< node x,y,z coordinates (initially!) @@ -96,7 +97,7 @@ subroutine discretization_marc_init call buildCells(connectivity_cell,cellNodeDefinition,& elem,connectivity_elem) node0_cell = buildCellNodes(node0_elem) - + IP_reshaped = buildIPcoordinates(node0_cell) call discretization_init(materialAt, IP_reshaped, node0_cell) @@ -114,25 +115,42 @@ subroutine discretization_marc_init call geometry_plastic_nonlocal_setIPneighborhood(IPneighborhood(elem)) call geometry_plastic_nonlocal_results -end subroutine discretization_marc_init +end subroutine discretization_Marc_init !-------------------------------------------------------------------------------------------------- !> @brief Calculate and set current nodal and IP positions (including cell nodes) !-------------------------------------------------------------------------------------------------- -subroutine discretization_marc_UpdateNodeAndIpCoords(d_n) - +subroutine discretization_Marc_updateNodeAndIpCoords(d_n) + real(pReal), dimension(:,:), intent(in) :: d_n real(pReal), dimension(:,:), allocatable :: node_cell - + node_cell = buildCellNodes(discretization_NodeCoords0(1:3,1:maxval(discretization_Marc_FEM2DAMASK_node)) + d_n) call discretization_setNodeCoords(node_cell) call discretization_setIPcoords(buildIPcoordinates(node_cell)) -end subroutine discretization_marc_UpdateNodeAndIpCoords +end subroutine discretization_Marc_updateNodeAndIpCoords + + +!-------------------------------------------------------------------------------------------------- +!> @brief Calculate and set current nodal and IP positions (including cell nodes) +!-------------------------------------------------------------------------------------------------- +function discretization_marc_FEM2DAMASK_cell(IP_FEM,elem_FEM) result(cell) + + integer, intent(in) :: IP_FEM, elem_FEM + integer :: cell + + real(pReal), dimension(:,:), allocatable :: node_cell + + + cell = (discretization_Marc_FEM2DAMASK_elem(elem_FEM)-1)*discretization_nIPs + IP_FEM + + +end function discretization_marc_FEM2DAMASK_cell !-------------------------------------------------------------------------------------------------- From 97d426718ad7b6aa3a515645daedae5e287c1808 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 10 Apr 2021 21:16:57 +0200 Subject: [PATCH 160/219] following renames and access pattern --- src/DAMASK_Marc.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DAMASK_Marc.f90 b/src/DAMASK_Marc.f90 index a1ce8fa0d..43ec9b084 100644 --- a/src/DAMASK_Marc.f90 +++ b/src/DAMASK_Marc.f90 @@ -344,8 +344,8 @@ subroutine flux(f,ts,n,time) real(pReal), dimension(2), intent(out) :: & f + f(1) = homogenization_f_T(discretization_Marc_FEM2DAMASK_cell(n(3),n(1))) f(2) = 0.0_pReal - call thermal_conduction_getSource(f(1), n(3),mesh_FEM2DAMASK_elem(n(1))) end subroutine flux From 1133090b6cb1bfb2d8fa62d7f18c5e92c8f52ecb Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 10 Apr 2021 22:47:00 +0200 Subject: [PATCH 161/219] logfile does not contain much valuable information Marc automatically creates .out --- PRIVATE | 2 +- python/damask/solver/_marc.py | 29 +++++++++-------------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/PRIVATE b/PRIVATE index 129812414..1490f9741 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 1298124143e7e2901d0b9c2e79ab6388cb78a1e3 +Subproject commit 1490f97417664d6ae11d7ceafb6b98c9cc2dade1 diff --git a/python/damask/solver/_marc.py b/python/damask/solver/_marc.py index 14e21144a..26823911d 100644 --- a/python/damask/solver/_marc.py +++ b/python/damask/solver/_marc.py @@ -41,13 +41,9 @@ class Marc: return path_tools - def submit_job(self, - model, - job = 'job1', - logfile = False, + def submit_job(self, model, job, compile = False, - optimization = '', - ): + optimization = ''): usersub = Path(os.environ['DAMASK_ROOT'])/'src/DAMASK_Marc' usersub = usersub.parent/(usersub.name + ('.f90' if compile else '.marc')) @@ -64,22 +60,15 @@ class Marc: ' -prog ' + str(usersub.with_suffix('')) print(cmd) - if logfile is not None: - try: - f = open(logfile,'w+',newline='\n') - except TypeError: - f = logfile - else: - f = io.StringIO() - - proc = subprocess.Popen(shlex.split(cmd),stdout=f,stderr=subprocess.STDOUT) - proc.wait() - f.seek(0) + ret = subprocess.run(shlex.split(cmd),capture_output=True) try: - v = int(re.search('Exit number ([0-9]+)',''.join(f.readlines())).group(1)) + if 3004 != int(re.search('Exit number ([0-9]+)',ret.stderr.decode()).group(1)): + print(ret.stderr.decode()) + print(ret.stdout.decode()) + raise RuntimeError(f'Marc simulation failed ({v})') except (AttributeError,ValueError): + print(ret.stderr.decode()) + print(ret.stdout.decode()) raise RuntimeError('Marc simulation failed (unknown return value)') - if v != 3004: - raise RuntimeError(f'Marc simulation failed ({v})') From cfbb2d416f1f6638734a864858660ec7aa8567f9 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 10 Apr 2021 23:52:59 +0200 Subject: [PATCH 162/219] better example --- examples/.gitignore | 3 + examples/Marc/material.config | 429 -------------------------------- examples/Marc/material.yaml | 31 +++ examples/Marc/rotation.mud | Bin 20700 -> 0 bytes examples/Marc/sheet_r-value.dat | 406 ++++++++++++++++++++++++++++++ python/damask/solver/_marc.py | 4 +- 6 files changed, 442 insertions(+), 431 deletions(-) delete mode 100644 examples/Marc/material.config create mode 100644 examples/Marc/material.yaml delete mode 100644 examples/Marc/rotation.mud create mode 100644 examples/Marc/sheet_r-value.dat diff --git a/examples/.gitignore b/examples/.gitignore index 93d78295b..b832fb271 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -3,3 +3,6 @@ *.xdmf *.sta *.vt* +*.out +*.sts +*.t16 diff --git a/examples/Marc/material.config b/examples/Marc/material.config deleted file mode 100644 index 46ea44367..000000000 --- a/examples/Marc/material.config +++ /dev/null @@ -1,429 +0,0 @@ -#-------------------# - -#-------------------# - -{../ConfigFiles/Homogenization_None_Dummy.config} - -#-------------------# - -#-------------------# - -[Grain001] -(constituent) phase 1 texture 1 fraction 1.0 -[Grain002] -(constituent) phase 1 texture 2 fraction 1.0 -[Grain003] -(constituent) phase 1 texture 3 fraction 1.0 -[Grain004] -(constituent) phase 1 texture 4 fraction 1.0 -[Grain005] -(constituent) phase 1 texture 5 fraction 1.0 -[Grain006] -(constituent) phase 1 texture 6 fraction 1.0 -[Grain007] -(constituent) phase 1 texture 7 fraction 1.0 -[Grain008] -(constituent) phase 1 texture 8 fraction 1.0 -[Grain009] -(constituent) phase 1 texture 9 fraction 1.0 -[Grain010] -(constituent) phase 1 texture 10 fraction 1.0 -[Grain011] -(constituent) phase 1 texture 11 fraction 1.0 -[Grain012] -(constituent) phase 1 texture 12 fraction 1.0 -[Grain013] -(constituent) phase 1 texture 13 fraction 1.0 -[Grain014] -(constituent) phase 1 texture 14 fraction 1.0 -[Grain015] -(constituent) phase 1 texture 15 fraction 1.0 -[Grain016] -(constituent) phase 1 texture 16 fraction 1.0 -[Grain017] -(constituent) phase 1 texture 17 fraction 1.0 -[Grain018] -(constituent) phase 1 texture 18 fraction 1.0 -[Grain019] -(constituent) phase 1 texture 19 fraction 1.0 -[Grain020] -(constituent) phase 1 texture 20 fraction 1.0 -[Grain021] -(constituent) phase 1 texture 21 fraction 1.0 -[Grain022] -(constituent) phase 1 texture 22 fraction 1.0 -[Grain023] -(constituent) phase 1 texture 23 fraction 1.0 -[Grain024] -(constituent) phase 1 texture 24 fraction 1.0 -[Grain025] -(constituent) phase 1 texture 25 fraction 1.0 -[Grain026] -(constituent) phase 1 texture 26 fraction 1.0 -[Grain027] -(constituent) phase 1 texture 27 fraction 1.0 -[Grain028] -(constituent) phase 1 texture 28 fraction 1.0 -[Grain029] -(constituent) phase 1 texture 29 fraction 1.0 -[Grain030] -(constituent) phase 1 texture 30 fraction 1.0 -[Grain031] -(constituent) phase 1 texture 31 fraction 1.0 -[Grain032] -(constituent) phase 1 texture 32 fraction 1.0 -[Grain033] -(constituent) phase 1 texture 33 fraction 1.0 -[Grain034] -(constituent) phase 1 texture 34 fraction 1.0 -[Grain035] -(constituent) phase 1 texture 35 fraction 1.0 -[Grain036] -(constituent) phase 1 texture 36 fraction 1.0 -[Grain037] -(constituent) phase 1 texture 37 fraction 1.0 -[Grain038] -(constituent) phase 1 texture 38 fraction 1.0 -[Grain039] -(constituent) phase 1 texture 39 fraction 1.0 -[Grain040] -(constituent) phase 1 texture 40 fraction 1.0 -[Grain041] -(constituent) phase 1 texture 41 fraction 1.0 -[Grain042] -(constituent) phase 1 texture 42 fraction 1.0 -[Grain043] -(constituent) phase 1 texture 43 fraction 1.0 -[Grain044] -(constituent) phase 1 texture 44 fraction 1.0 -[Grain045] -(constituent) phase 1 texture 45 fraction 1.0 -[Grain046] -(constituent) phase 1 texture 46 fraction 1.0 -[Grain047] -(constituent) phase 1 texture 47 fraction 1.0 -[Grain048] -(constituent) phase 1 texture 48 fraction 1.0 -[Grain049] -(constituent) phase 1 texture 49 fraction 1.0 -[Grain050] -(constituent) phase 1 texture 50 fraction 1.0 -[Grain051] -(constituent) phase 1 texture 51 fraction 1.0 -[Grain052] -(constituent) phase 1 texture 52 fraction 1.0 -[Grain053] -(constituent) phase 1 texture 53 fraction 1.0 -[Grain054] -(constituent) phase 1 texture 54 fraction 1.0 -[Grain055] -(constituent) phase 1 texture 55 fraction 1.0 -[Grain056] -(constituent) phase 1 texture 56 fraction 1.0 -[Grain057] -(constituent) phase 1 texture 57 fraction 1.0 -[Grain058] -(constituent) phase 1 texture 58 fraction 1.0 -[Grain059] -(constituent) phase 1 texture 59 fraction 1.0 -[Grain060] -(constituent) phase 1 texture 60 fraction 1.0 -[Grain061] -(constituent) phase 1 texture 61 fraction 1.0 -[Grain062] -(constituent) phase 1 texture 62 fraction 1.0 -[Grain063] -(constituent) phase 1 texture 63 fraction 1.0 -[Grain064] -(constituent) phase 1 texture 64 fraction 1.0 -[Grain065] -(constituent) phase 1 texture 65 fraction 1.0 -[Grain066] -(constituent) phase 1 texture 66 fraction 1.0 -[Grain067] -(constituent) phase 1 texture 67 fraction 1.0 -[Grain068] -(constituent) phase 1 texture 68 fraction 1.0 -[Grain069] -(constituent) phase 1 texture 69 fraction 1.0 -[Grain070] -(constituent) phase 1 texture 70 fraction 1.0 -[Grain071] -(constituent) phase 1 texture 71 fraction 1.0 -[Grain072] -(constituent) phase 1 texture 72 fraction 1.0 -[Grain073] -(constituent) phase 1 texture 73 fraction 1.0 -[Grain074] -(constituent) phase 1 texture 74 fraction 1.0 -[Grain075] -(constituent) phase 1 texture 75 fraction 1.0 -[Grain076] -(constituent) phase 1 texture 76 fraction 1.0 -[Grain077] -(constituent) phase 1 texture 77 fraction 1.0 -[Grain078] -(constituent) phase 1 texture 78 fraction 1.0 -[Grain079] -(constituent) phase 1 texture 79 fraction 1.0 -[Grain080] -(constituent) phase 1 texture 80 fraction 1.0 -[Grain081] -(constituent) phase 1 texture 81 fraction 1.0 -[Grain082] -(constituent) phase 1 texture 82 fraction 1.0 -[Grain083] -(constituent) phase 1 texture 83 fraction 1.0 -[Grain084] -(constituent) phase 1 texture 84 fraction 1.0 -[Grain085] -(constituent) phase 1 texture 85 fraction 1.0 -[Grain086] -(constituent) phase 1 texture 86 fraction 1.0 -[Grain087] -(constituent) phase 1 texture 87 fraction 1.0 -[Grain088] -(constituent) phase 1 texture 88 fraction 1.0 -[Grain089] -(constituent) phase 1 texture 89 fraction 1.0 -[Grain090] -(constituent) phase 1 texture 90 fraction 1.0 -[Grain091] -(constituent) phase 1 texture 91 fraction 1.0 -[Grain092] -(constituent) phase 1 texture 92 fraction 1.0 -[Grain093] -(constituent) phase 1 texture 93 fraction 1.0 -[Grain094] -(constituent) phase 1 texture 94 fraction 1.0 -[Grain095] -(constituent) phase 1 texture 95 fraction 1.0 -[Grain096] -(constituent) phase 1 texture 96 fraction 1.0 -[Grain097] -(constituent) phase 1 texture 97 fraction 1.0 -[Grain098] -(constituent) phase 1 texture 98 fraction 1.0 -[Grain099] -(constituent) phase 1 texture 99 fraction 1.0 -[Grain100] -(constituent) phase 1 texture 100 fraction 1.0 -[cubeGrain] -(constituent) phase 1 texture 101 fraction 1.0 - -#-------------------# - -#-------------------# - -[Grain001] -(gauss) phi1 359.121452 Phi 82.319471 Phi2 347.729535 -[Grain002] -(gauss) phi1 269.253967 Phi 105.379919 Phi2 173.029284 -[Grain003] -(gauss) phi1 26.551535 Phi 171.606752 Phi2 124.949264 -[Grain004] -(gauss) phi1 123.207774 Phi 124.339577 Phi2 47.937748 -[Grain005] -(gauss) phi1 324.188825 Phi 103.089216 Phi2 160.373624 -[Grain006] -(gauss) phi1 238.295585 Phi 165.416882 Phi2 234.307741 -[Grain007] -(gauss) phi1 232.707177 Phi 110.733726 Phi2 308.049265 -[Grain008] -(gauss) phi1 144.463291 Phi 125.891441 Phi2 348.674207 -[Grain009] -(gauss) phi1 215.423832 Phi 69.759502 Phi2 164.477632 -[Grain010] -(gauss) phi1 118.805444 Phi 143.057031 Phi2 271.963190 -[Grain011] -(gauss) phi1 218.049576 Phi 64.017550 Phi2 323.040457 -[Grain012] -(gauss) phi1 236.962483 Phi 134.312093 Phi2 220.433366 -[Grain013] -(gauss) phi1 352.317686 Phi 3.356527 Phi2 92.447275 -[Grain014] -(gauss) phi1 198.311545 Phi 71.452240 Phi2 199.441849 -[Grain015] -(gauss) phi1 351.993635 Phi 36.500987 Phi2 236.852886 -[Grain016] -(gauss) phi1 262.389063 Phi 101.249950 Phi2 334.305959 -[Grain017] -(gauss) phi1 53.220668 Phi 69.570254 Phi2 277.061151 -[Grain018] -(gauss) phi1 122.156119 Phi 140.207051 Phi2 221.172906 -[Grain019] -(gauss) phi1 295.422170 Phi 26.595511 Phi2 263.206315 -[Grain020] -(gauss) phi1 179.137406 Phi 104.500977 Phi2 151.742108 -[Grain021] -(gauss) phi1 199.045094 Phi 5.228899 Phi2 356.542109 -[Grain022] -(gauss) phi1 268.671476 Phi 24.835403 Phi2 33.578889 -[Grain023] -(gauss) phi1 264.248527 Phi 59.766630 Phi2 340.865462 -[Grain024] -(gauss) phi1 254.223491 Phi 51.125301 Phi2 201.094027 -[Grain025] -(gauss) phi1 22.214008 Phi 92.248774 Phi2 215.168318 -[Grain026] -(gauss) phi1 49.511491 Phi 79.933539 Phi2 187.188575 -[Grain027] -(gauss) phi1 318.916204 Phi 113.102650 Phi2 241.076629 -[Grain028] -(gauss) phi1 239.378433 Phi 89.578655 Phi2 94.167043 -[Grain029] -(gauss) phi1 27.561421 Phi 142.892093 Phi2 197.735666 -[Grain030] -(gauss) phi1 135.210581 Phi 165.859834 Phi2 285.449561 -[Grain031] -(gauss) phi1 223.515916 Phi 56.824378 Phi2 343.289074 -[Grain032] -(gauss) phi1 41.127974 Phi 111.289145 Phi2 214.855145 -[Grain033] -(gauss) phi1 17.335045 Phi 140.496745 Phi2 77.747371 -[Grain034] -(gauss) phi1 36.206421 Phi 148.574232 Phi2 88.870226 -[Grain035] -(gauss) phi1 159.618336 Phi 125.680504 Phi2 204.119403 -[Grain036] -(gauss) phi1 8.752464 Phi 99.173166 Phi2 143.227089 -[Grain037] -(gauss) phi1 351.570753 Phi 67.343218 Phi2 1.779612 -[Grain038] -(gauss) phi1 46.771572 Phi 155.018674 Phi2 302.319987 -[Grain039] -(gauss) phi1 244.255976 Phi 80.566566 Phi2 264.069331 -[Grain040] -(gauss) phi1 41.775388 Phi 47.109507 Phi2 300.598550 -[Grain041] -(gauss) phi1 268.753103 Phi 46.654050 Phi2 190.382041 -[Grain042] -(gauss) phi1 239.574480 Phi 62.517793 Phi2 147.817535 -[Grain043] -(gauss) phi1 128.059775 Phi 61.916743 Phi2 169.674359 -[Grain044] -(gauss) phi1 166.545156 Phi 58.709099 Phi2 252.885391 -[Grain045] -(gauss) phi1 92.867691 Phi 28.906456 Phi2 164.197290 -[Grain046] -(gauss) phi1 291.056147 Phi 35.145174 Phi2 250.155599 -[Grain047] -(gauss) phi1 79.015862 Phi 44.772479 Phi2 267.982808 -[Grain048] -(gauss) phi1 108.400702 Phi 69.883075 Phi2 222.737053 -[Grain049] -(gauss) phi1 348.326500 Phi 11.339714 Phi2 121.682346 -[Grain050] -(gauss) phi1 331.476209 Phi 108.775043 Phi2 335.139671 -[Grain051] -(gauss) phi1 196.750278 Phi 93.955106 Phi2 63.689075 -[Grain052] -(gauss) phi1 136.077875 Phi 130.508342 Phi2 128.468976 -[Grain053] -(gauss) phi1 239.643513 Phi 76.284643 Phi2 168.821008 -[Grain054] -(gauss) phi1 113.850670 Phi 117.531757 Phi2 71.971648 -[Grain055] -(gauss) phi1 149.554071 Phi 16.543098 Phi2 195.556172 -[Grain056] -(gauss) phi1 46.626579 Phi 52.447846 Phi2 304.495569 -[Grain057] -(gauss) phi1 255.251821 Phi 86.678048 Phi2 238.982712 -[Grain058] -(gauss) phi1 324.266133 Phi 28.075458 Phi2 41.191295 -[Grain059] -(gauss) phi1 312.000332 Phi 74.648725 Phi2 87.403581 -[Grain060] -(gauss) phi1 57.742481 Phi 163.241519 Phi2 68.491438 -[Grain061] -(gauss) phi1 112.442447 Phi 51.735320 Phi2 206.538656 -[Grain062] -(gauss) phi1 297.453842 Phi 115.283041 Phi2 57.785319 -[Grain063] -(gauss) phi1 119.132681 Phi 117.923565 Phi2 196.121206 -[Grain064] -(gauss) phi1 199.267314 Phi 163.091476 Phi2 53.549301 -[Grain065] -(gauss) phi1 37.765215 Phi 76.795488 Phi2 146.264753 -[Grain066] -(gauss) phi1 324.550183 Phi 27.665150 Phi2 56.383148 -[Grain067] -(gauss) phi1 337.305377 Phi 136.807151 Phi2 133.661586 -[Grain068] -(gauss) phi1 115.744041 Phi 64.536978 Phi2 262.694800 -[Grain069] -(gauss) phi1 136.293403 Phi 48.862462 Phi2 343.319175 -[Grain070] -(gauss) phi1 111.030931 Phi 80.823213 Phi2 84.041594 -[Grain071] -(gauss) phi1 303.985249 Phi 118.929631 Phi2 302.307709 -[Grain072] -(gauss) phi1 193.556259 Phi 75.928015 Phi2 176.696899 -[Grain073] -(gauss) phi1 102.543259 Phi 121.929923 Phi2 234.496773 -[Grain074] -(gauss) phi1 218.581323 Phi 101.753894 Phi2 305.566089 -[Grain075] -(gauss) phi1 229.542114 Phi 118.839215 Phi2 129.179156 -[Grain076] -(gauss) phi1 202.258840 Phi 139.205956 Phi2 352.248979 -[Grain077] -(gauss) phi1 137.954289 Phi 63.806918 Phi2 128.975049 -[Grain078] -(gauss) phi1 327.557366 Phi 84.987420 Phi2 345.483143 -[Grain079] -(gauss) phi1 334.610243 Phi 74.535474 Phi2 106.419231 -[Grain080] -(gauss) phi1 62.906243 Phi 46.752029 Phi2 222.692276 -[Grain081] -(gauss) phi1 254.121439 Phi 121.005485 Phi2 287.265977 -[Grain082] -(gauss) phi1 140.765045 Phi 141.268031 Phi2 271.327656 -[Grain083] -(gauss) phi1 10.726984 Phi 66.339177 Phi2 189.073212 -[Grain084] -(gauss) phi1 270.921536 Phi 72.821127 Phi2 313.590515 -[Grain085] -(gauss) phi1 299.059668 Phi 23.884874 Phi2 80.016277 -[Grain086] -(gauss) phi1 208.617406 Phi 11.031834 Phi2 302.388247 -[Grain087] -(gauss) phi1 62.929967 Phi 65.223261 Phi2 108.558265 -[Grain088] -(gauss) phi1 9.014959 Phi 33.542169 Phi2 247.970366 -[Grain089] -(gauss) phi1 272.432808 Phi 30.065174 Phi2 19.803570 -[Grain090] -(gauss) phi1 179.621980 Phi 151.763475 Phi2 61.871794 -[Grain091] -(gauss) phi1 247.810321 Phi 112.752980 Phi2 264.668469 -[Grain092] -(gauss) phi1 270.780630 Phi 102.037858 Phi2 31.602610 -[Grain093] -(gauss) phi1 17.626672 Phi 56.032415 Phi2 245.079600 -[Grain094] -(gauss) phi1 112.165186 Phi 87.390459 Phi2 182.086729 -[Grain095] -(gauss) phi1 157.869381 Phi 79.905131 Phi2 107.037081 -[Grain096] -(gauss) phi1 106.163846 Phi 148.477084 Phi2 350.980466 -[Grain097] -(gauss) phi1 262.138550 Phi 58.923588 Phi2 111.303439 -[Grain098] -(gauss) phi1 88.739397 Phi 119.092789 Phi2 222.502594 -[Grain099] -(gauss) phi1 337.603765 Phi 10.145102 Phi2 80.934916 -[Grain100] -(gauss) phi1 341.022242 Phi 45.927285 Phi2 252.045476 - -[cube] -(gauss) phi1 0 Phi 0 phi2 0 - - -#-------------------# - -#-------------------# - -{../ConfigFiles/Phase_Phenopowerlaw_Aluminum.config} - -{../ConfigFiles/Phase_Isotropic_AluminumIsotropic.config} diff --git a/examples/Marc/material.yaml b/examples/Marc/material.yaml new file mode 100644 index 000000000..5c893ac52 --- /dev/null +++ b/examples/Marc/material.yaml @@ -0,0 +1,31 @@ +--- +homogenization: + SX: + N_constituents: 1 + mechanical: {type: pass} + +phase: + Aluminum: + lattice: cF + mechanical: + output: [F, P, F_e, F_p, L_p, O] + elastic: {type: Hooke, C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9} + plastic: + type: phenopowerlaw + N_sl: [12] + a_sl: 2.25 + atol_xi: 1.0 + dot_gamma_0_sl: 0.001 + h_0_sl_sl: 75e6 + h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4] + n_sl: 20 + output: [xi_sl] + xi_0_sl: [31e6] + xi_inf_sl: [63e6] + +material: + - homogenization: SX + constituents: + - phase: Aluminum + v: 1.0 + O: [0.9330127018922194, 0.25, 0.06698729810778066, 0.25] diff --git a/examples/Marc/rotation.mud b/examples/Marc/rotation.mud deleted file mode 100644 index 21eff797487e1eb32b16d7463f7543ecb34797f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20700 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 KQNdI{9_c@eI>7D# diff --git a/examples/Marc/sheet_r-value.dat b/examples/Marc/sheet_r-value.dat new file mode 100644 index 000000000..529f4d31a --- /dev/null +++ b/examples/Marc/sheet_r-value.dat @@ -0,0 +1,406 @@ +title r-value +$....MARC input file produced by Marc Mentat 2019 (64bit) +$................................... +$....input file using extended precision +extended +$................................... +sizing 0 80 165 0 +alloc 25 +elements 7 +version 14 1 0 1 +table 0 0 2 1 1 0 0 1 +processor 1 1 1 0 +$no list +large stra 2 1 0 0 0 0 0 +all points +no echo 1 2 3 4 +state vars 3 +end +$................... +solver + 8 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +optimize 11 +connectivity + 0 0 1 0 1 1 0 0 0 + 1 7 2 5 20 17 1 4 19 16 + 2 7 3 6 21 18 2 5 20 17 + 3 7 5 8 23 20 4 7 22 19 + 4 7 6 9 24 21 5 8 23 20 + 5 7 8 11 26 23 7 10 25 22 + 6 7 9 12 27 24 8 11 26 23 + 7 7 11 14 29 26 10 13 28 25 + 8 7 12 15 30 27 11 14 29 26 + 9 7 17 20 35 32 16 19 34 31 + 10 7 18 21 36 33 17 20 35 32 + 11 7 20 23 38 35 19 22 37 34 + 12 7 21 24 39 36 20 23 38 35 + 13 7 23 26 41 38 22 25 40 37 + 14 7 24 27 42 39 23 26 41 38 + 15 7 26 29 44 41 25 28 43 40 + 16 7 27 30 45 42 26 29 44 41 + 17 7 32 35 50 47 31 34 49 46 + 18 7 33 36 51 48 32 35 50 47 + 19 7 35 38 53 50 34 37 52 49 + 20 7 36 39 54 51 35 38 53 50 + 21 7 38 41 56 53 37 40 55 52 + 22 7 39 42 57 54 38 41 56 53 + 23 7 41 44 59 56 40 43 58 55 + 24 7 42 45 60 57 41 44 59 56 + 25 7 47 50 65 62 46 49 64 61 + 26 7 48 51 66 63 47 50 65 62 + 27 7 50 53 68 65 49 52 67 64 + 28 7 51 54 69 66 50 53 68 65 + 29 7 53 56 71 68 52 55 70 67 + 30 7 54 57 72 69 53 56 71 68 + 31 7 56 59 74 71 55 58 73 70 + 32 7 57 60 75 72 56 59 74 71 + 33 7 62 65 80 77 61 64 79 76 + 34 7 63 66 81 78 62 65 80 77 + 35 7 65 68 83 80 64 67 82 79 + 36 7 66 69 84 81 65 68 83 80 + 37 7 68 71 86 83 67 70 85 82 + 38 7 69 72 87 84 68 71 86 83 + 39 7 71 74 89 86 70 73 88 85 + 40 7 72 75 90 87 71 74 89 86 + 41 7 77 80 95 92 76 79 94 91 + 42 7 78 81 96 93 77 80 95 92 + 43 7 80 83 98 95 79 82 97 94 + 44 7 81 84 99 96 80 83 98 95 + 45 7 83 86 101 98 82 85 100 97 + 46 7 84 87 102 99 83 86 101 98 + 47 7 86 89 104 101 85 88 103 100 + 48 7 87 90 105 102 86 89 104 101 + 49 7 92 95 110 107 91 94 109 106 + 50 7 93 96 111 108 92 95 110 107 + 51 7 95 98 113 110 94 97 112 109 + 52 7 96 99 114 111 95 98 113 110 + 53 7 98 101 116 113 97 100 115 112 + 54 7 99 102 117 114 98 101 116 113 + 55 7 101 104 119 116 100 103 118 115 + 56 7 102 105 120 117 101 104 119 116 + 57 7 107 110 125 122 106 109 124 121 + 58 7 108 111 126 123 107 110 125 122 + 59 7 110 113 128 125 109 112 127 124 + 60 7 111 114 129 126 110 113 128 125 + 61 7 113 116 131 128 112 115 130 127 + 62 7 114 117 132 129 113 116 131 128 + 63 7 116 119 134 131 115 118 133 130 + 64 7 117 120 135 132 116 119 134 131 + 65 7 122 125 140 137 121 124 139 136 + 66 7 123 126 141 138 122 125 140 137 + 67 7 125 128 143 140 124 127 142 139 + 68 7 126 129 144 141 125 128 143 140 + 69 7 128 131 146 143 127 130 145 142 + 70 7 129 132 147 144 128 131 146 143 + 71 7 131 134 149 146 130 133 148 145 + 72 7 132 135 150 147 131 134 149 146 + 73 7 137 140 155 152 136 139 154 151 + 74 7 138 141 156 153 137 140 155 152 + 75 7 140 143 158 155 139 142 157 154 + 76 7 141 144 159 156 140 143 158 155 + 77 7 143 146 161 158 142 145 160 157 + 78 7 144 147 162 159 143 146 161 158 + 79 7 146 149 164 161 145 148 163 160 + 80 7 147 150 165 162 146 149 164 161 +coordinates + 3 165 0 1 + 1-4.000000000000000+1-1.000000000000000+1-5.000000000000000-1 + 2-4.000000000000000+1-1.000000000000000+1 0.000000000000000+0 + 3-4.000000000000000+1-1.000000000000000+1 5.000000000000000-1 + 4-4.000000000000000+1-5.000000000000000+0-5.000000000000000-1 + 5-4.000000000000000+1-5.000000000000000+0 0.000000000000000+0 + 6-4.000000000000000+1-5.000000000000000+0 5.000000000000000-1 + 7-4.000000000000000+1 0.000000000000000+0-5.000000000000000-1 + 8-4.000000000000000+1 0.000000000000000+0 0.000000000000000+0 + 9-4.000000000000000+1 0.000000000000000+0 5.000000000000000-1 + 10-4.000000000000000+1 5.000000000000000+0-5.000000000000000-1 + 11-4.000000000000000+1 5.000000000000000+0 0.000000000000000+0 + 12-4.000000000000000+1 5.000000000000000+0 5.000000000000000-1 + 13-4.000000000000000+1 9.999999999999996+0-5.000000000000000-1 + 14-4.000000000000000+1 9.999999999999996+0 0.000000000000000+0 + 15-4.000000000000000+1 9.999999999999996+0 5.000000000000000-1 + 16-3.200000000000000+1-1.000000000000000+1-5.000000000000000-1 + 17-3.200000000000000+1-1.000000000000000+1 0.000000000000000+0 + 18-3.200000000000000+1-1.000000000000000+1 5.000000000000000-1 + 19-3.200000000000000+1-5.000000000000000+0-5.000000000000000-1 + 20-3.200000000000000+1-5.000000000000000+0 0.000000000000000+0 + 21-3.200000000000000+1-5.000000000000000+0 5.000000000000000-1 + 22-3.200000000000000+1 0.000000000000000+0-5.000000000000000-1 + 23-3.200000000000000+1 0.000000000000000+0 0.000000000000000+0 + 24-3.200000000000000+1 0.000000000000000+0 5.000000000000000-1 + 25-3.200000000000000+1 5.000000000000000+0-5.000000000000000-1 + 26-3.200000000000000+1 5.000000000000000+0 0.000000000000000+0 + 27-3.200000000000000+1 5.000000000000000+0 5.000000000000000-1 + 28-3.200000000000000+1 1.000000000000000+1-5.000000000000000-1 + 29-3.200000000000000+1 1.000000000000000+1 0.000000000000000+0 + 30-3.200000000000000+1 1.000000000000000+1 5.000000000000000-1 + 31-2.400000000000001+1-1.000000000000000+1-5.000000000000000-1 + 32-2.400000000000001+1-1.000000000000000+1 0.000000000000000+0 + 33-2.400000000000001+1-1.000000000000000+1 5.000000000000000-1 + 34-2.400000000000000+1-5.000000000000000+0-5.000000000000000-1 + 35-2.400000000000000+1-5.000000000000000+0 0.000000000000000+0 + 36-2.400000000000000+1-5.000000000000000+0 5.000000000000000-1 + 37-2.400000000000001+1 0.000000000000000+0-5.000000000000000-1 + 38-2.400000000000001+1 0.000000000000000+0 0.000000000000000+0 + 39-2.400000000000001+1 0.000000000000000+0 5.000000000000000-1 + 40-2.400000000000001+1 5.000000000000002+0-5.000000000000000-1 + 41-2.400000000000001+1 5.000000000000002+0 0.000000000000000+0 + 42-2.400000000000001+1 5.000000000000002+0 5.000000000000000-1 + 43-2.400000000000001+1 9.999999999999996+0-5.000000000000000-1 + 44-2.400000000000001+1 9.999999999999996+0 0.000000000000000+0 + 45-2.400000000000001+1 9.999999999999996+0 5.000000000000000-1 + 46-1.600000000000000+1-1.000000000000000+1-5.000000000000000-1 + 47-1.600000000000000+1-1.000000000000000+1 0.000000000000000+0 + 48-1.600000000000000+1-1.000000000000000+1 5.000000000000000-1 + 49-1.600000000000000+1-5.000000000000000+0-5.000000000000000-1 + 50-1.600000000000000+1-5.000000000000000+0 0.000000000000000+0 + 51-1.600000000000000+1-5.000000000000000+0 5.000000000000000-1 + 52-1.600000000000000+1 0.000000000000000+0-5.000000000000000-1 + 53-1.600000000000000+1 0.000000000000000+0 0.000000000000000+0 + 54-1.600000000000000+1 0.000000000000000+0 5.000000000000000-1 + 55-1.600000000000000+1 4.999999999999998+0-5.000000000000000-1 + 56-1.600000000000000+1 4.999999999999998+0 0.000000000000000+0 + 57-1.600000000000000+1 4.999999999999998+0 5.000000000000000-1 + 58-1.600000000000000+1 9.999999999999996+0-5.000000000000000-1 + 59-1.600000000000000+1 9.999999999999996+0 0.000000000000000+0 + 60-1.600000000000000+1 9.999999999999996+0 5.000000000000000-1 + 61-8.000000000000000+0-1.000000000000000+1-5.000000000000000-1 + 62-8.000000000000000+0-1.000000000000000+1 0.000000000000000+0 + 63-8.000000000000000+0-1.000000000000000+1 5.000000000000000-1 + 64-7.999999999999994+0-5.000000000000000+0-5.000000000000000-1 + 65-7.999999999999994+0-5.000000000000000+0 0.000000000000000+0 + 66-7.999999999999994+0-5.000000000000000+0 5.000000000000000-1 + 67-8.000000000000000+0 0.000000000000000+0-5.000000000000000-1 + 68-8.000000000000000+0 0.000000000000000+0 0.000000000000000+0 + 69-8.000000000000000+0 0.000000000000000+0 5.000000000000000-1 + 70-8.000000000000000+0 5.000000000000000+0-5.000000000000000-1 + 71-8.000000000000000+0 5.000000000000000+0 0.000000000000000+0 + 72-8.000000000000000+0 5.000000000000000+0 5.000000000000000-1 + 73-8.000000000000000+0 9.999999999999996+0-5.000000000000000-1 + 74-8.000000000000000+0 9.999999999999996+0 0.000000000000000+0 + 75-8.000000000000000+0 9.999999999999996+0 5.000000000000000-1 + 76 0.000000000000000+0-1.000000000000000+1-5.000000000000000-1 + 77 0.000000000000000+0-1.000000000000000+1 0.000000000000000+0 + 78 0.000000000000000+0-1.000000000000000+1 5.000000000000000-1 + 79 0.000000000000000+0-5.000000000000000+0-5.000000000000000-1 + 80 0.000000000000000+0-5.000000000000000+0 0.000000000000000+0 + 81 0.000000000000000+0-5.000000000000000+0 5.000000000000000-1 + 82 0.000000000000000+0 0.000000000000000+0-5.000000000000000-1 + 83 0.000000000000000+0 0.000000000000000+0 0.000000000000000+0 + 84 0.000000000000000+0 0.000000000000000+0 5.000000000000000-1 + 85 0.000000000000000+0 5.000000000000000+0-5.000000000000000-1 + 86 0.000000000000000+0 5.000000000000000+0 0.000000000000000+0 + 87 0.000000000000000+0 5.000000000000000+0 5.000000000000000-1 + 88 0.000000000000000+0 9.999999999999996+0-5.000000000000000-1 + 89 0.000000000000000+0 9.999999999999996+0 0.000000000000000+0 + 90 0.000000000000000+0 9.999999999999996+0 5.000000000000000-1 + 91 8.000000000000000+0-1.000000000000000+1-5.000000000000000-1 + 92 8.000000000000000+0-1.000000000000000+1 0.000000000000000+0 + 93 8.000000000000000+0-1.000000000000000+1 5.000000000000000-1 + 94 8.000000000000000+0-5.000000000000000+0-5.000000000000000-1 + 95 8.000000000000000+0-5.000000000000000+0 0.000000000000000+0 + 96 8.000000000000000+0-5.000000000000000+0 5.000000000000000-1 + 97 8.000000000000000+0 0.000000000000000+0-5.000000000000000-1 + 98 8.000000000000000+0 0.000000000000000+0 0.000000000000000+0 + 99 8.000000000000000+0 0.000000000000000+0 5.000000000000000-1 + 100 8.000000000000000+0 5.000000000000000+0-5.000000000000000-1 + 101 8.000000000000000+0 5.000000000000000+0 0.000000000000000+0 + 102 8.000000000000000+0 5.000000000000000+0 5.000000000000000-1 + 103 7.999999999999994+0 9.999999999999996+0-5.000000000000000-1 + 104 7.999999999999994+0 9.999999999999996+0 0.000000000000000+0 + 105 7.999999999999994+0 9.999999999999996+0 5.000000000000000-1 + 106 1.600000000000000+1-1.000000000000000+1-5.000000000000000-1 + 107 1.600000000000000+1-1.000000000000000+1 0.000000000000000+0 + 108 1.600000000000000+1-1.000000000000000+1 5.000000000000000-1 + 109 1.600000000000000+1-5.000000000000000+0-5.000000000000000-1 + 110 1.600000000000000+1-5.000000000000000+0 0.000000000000000+0 + 111 1.600000000000000+1-5.000000000000000+0 5.000000000000000-1 + 112 1.600000000000000+1 0.000000000000000+0-5.000000000000000-1 + 113 1.600000000000000+1 0.000000000000000+0 0.000000000000000+0 + 114 1.600000000000000+1 0.000000000000000+0 5.000000000000000-1 + 115 1.600000000000000+1 5.000000000000000+0-5.000000000000000-1 + 116 1.600000000000000+1 5.000000000000000+0 0.000000000000000+0 + 117 1.600000000000000+1 5.000000000000000+0 5.000000000000000-1 + 118 1.600000000000000+1 9.999999999999996+0-5.000000000000000-1 + 119 1.600000000000000+1 9.999999999999996+0 0.000000000000000+0 + 120 1.600000000000000+1 9.999999999999996+0 5.000000000000000-1 + 121 2.400000000000000+1-1.000000000000000+1-5.000000000000000-1 + 122 2.400000000000000+1-1.000000000000000+1 0.000000000000000+0 + 123 2.400000000000000+1-1.000000000000000+1 5.000000000000000-1 + 124 2.400000000000001+1-5.000000000000000+0-5.000000000000000-1 + 125 2.400000000000001+1-5.000000000000000+0 0.000000000000000+0 + 126 2.400000000000001+1-5.000000000000000+0 5.000000000000000-1 + 127 2.400000000000000+1 0.000000000000000+0-5.000000000000000-1 + 128 2.400000000000000+1 0.000000000000000+0 0.000000000000000+0 + 129 2.400000000000000+1 0.000000000000000+0 5.000000000000000-1 + 130 2.400000000000001+1 5.000000000000000+0-5.000000000000000-1 + 131 2.400000000000001+1 5.000000000000000+0 0.000000000000000+0 + 132 2.400000000000001+1 5.000000000000000+0 5.000000000000000-1 + 133 2.400000000000000+1 9.999999999999996+0-5.000000000000000-1 + 134 2.400000000000000+1 9.999999999999996+0 0.000000000000000+0 + 135 2.400000000000000+1 9.999999999999996+0 5.000000000000000-1 + 136 3.200000000000000+1-1.000000000000000+1-5.000000000000000-1 + 137 3.200000000000000+1-1.000000000000000+1 0.000000000000000+0 + 138 3.200000000000000+1-1.000000000000000+1 5.000000000000000-1 + 139 3.199999999999999+1-5.000000000000000+0-5.000000000000000-1 + 140 3.199999999999999+1-5.000000000000000+0 0.000000000000000+0 + 141 3.199999999999999+1-5.000000000000000+0 5.000000000000000-1 + 142 3.200000000000000+1 0.000000000000000+0-5.000000000000000-1 + 143 3.200000000000000+1 0.000000000000000+0 0.000000000000000+0 + 144 3.200000000000000+1 0.000000000000000+0 5.000000000000000-1 + 145 3.200000000000000+1 5.000000000000000+0-5.000000000000000-1 + 146 3.200000000000000+1 5.000000000000000+0 0.000000000000000+0 + 147 3.200000000000000+1 5.000000000000000+0 5.000000000000000-1 + 148 3.199999999999999+1 9.999999999999996+0-5.000000000000000-1 + 149 3.199999999999999+1 9.999999999999996+0 0.000000000000000+0 + 150 3.199999999999999+1 9.999999999999996+0 5.000000000000000-1 + 151 3.999999999999999+1-1.000000000000000+1-5.000000000000000-1 + 152 3.999999999999999+1-1.000000000000000+1 0.000000000000000+0 + 153 3.999999999999999+1-1.000000000000000+1 5.000000000000000-1 + 154 3.999999999999999+1-5.000000000000000+0-5.000000000000000-1 + 155 3.999999999999999+1-5.000000000000000+0 0.000000000000000+0 + 156 3.999999999999999+1-5.000000000000000+0 5.000000000000000-1 + 157 3.999999999999999+1 0.000000000000000+0-5.000000000000000-1 + 158 3.999999999999999+1 0.000000000000000+0 0.000000000000000+0 + 159 3.999999999999999+1 0.000000000000000+0 5.000000000000000-1 + 160 3.999999999999999+1 5.000000000000000+0-5.000000000000000-1 + 161 3.999999999999999+1 5.000000000000000+0 0.000000000000000+0 + 162 3.999999999999999+1 5.000000000000000+0 5.000000000000000-1 + 163 3.999999999999999+1 9.999999999999996+0-5.000000000000000-1 + 164 3.999999999999999+1 9.999999999999996+0 0.000000000000000+0 + 165 3.999999999999999+1 9.999999999999996+0 5.000000000000000-1 +define element set Material_Nummer_elements + 1 to 80 +define node set unten_y_nodes + 2 5 8 11 14 +define node set oben_y_nodes + 152 155 158 161 164 +define node set unten_fest_nodes + 1 to 15 +define node set oben_ziehen_nodes + 151 to 165 +define node set unten_z_nodes + 7 to 9 +define node set oben_z_nodes + 157 to 159 +define element set texture_elements + 1 to 80 +hypoelastic + + 1 0 1 0 1TKS 0 + 1.000000000000000+0 0.000000000000000+0 0.000000000000000+0 0.000000000000000+0 0.000000000000000+0 0.000000000000000+0 0.000000000000000+0 + 0 0 0 0 0 0 0 + +mat color + + 1 1 230 0 0 +table weg_x + 1 1 0 0 2 + 1 2 2 0 0 2 0 0 2 0 0 2 + 0.000000000000000+0 0.000000000000000+0 + 2.000000000000000+2 1.600000000000000+1 +geometry + 0 0 2 + 1 9 1 230 0 0 +r-value-sample + 0.000000000000000+0 0.000000000000000+0 0.000000000000000+0 0.000000000000000+0 0.000000000000000+0 0.000000000000000+0 0.000000000000000+0 + +usdata 1 +fixed disp + + 1 0 0 0 1 0unten_z + 0.000000000000000+0 0.000000000000000+0 + 0 0 + 1 2 + 2 +unten_z_nodes + 1 0 0 0 1 0unten_y + 0.000000000000000+0 0.000000000000000+0 + 0 0 + 1 3 + 2 +unten_y_nodes + 1 0 0 0 1 0oben_z + 1.000000000000000+0 0.000000000000000+0 + 1 0 + 1 2 + 2 +oben_z_nodes + 1 0 0 0 1 0oben_y + 1.000000000000000+0 0.000000000000000+0 + 1 0 + 1 3 + 2 +oben_y_nodes + 1 0 0 0 1 0unten_fest + 0.000000000000000+0 + 0 + 1 + 2 +unten_fest_nodes + 1 0 0 0 1 0oben_ziehen + 1.000000000000000+0 + 1 + 1 + 2 +oben_ziehen_nodes +initial state + + 2 6 1 0 0 0Material_Nummer + 1.000000000000000+0 + 0 + 1 +Material_Nummer_elements +initial state + + 3 6 1 0 0 0texture + 1.000000000000000+0 + 0 + 1 +texture_elements +loadcase r-value + 5 +Material_Nummer +texture +unten_z +unten_y +unten_fest +no print +post + 6 16 17 0 0 19 20 0 1 0 0 0 0 0 0 0 +parameters + 1.000000000000000+0 1.000000000000000+9 1.000000000000000+2 1.000000000000000+6 2.500000000000000-1 5.000000000000000-1 1.500000000000000+0-5.000000000000000-1 + 8.625000000000000+0 2.000000000000000+1 1.000000000000000-4 1.000000000000000-6 1.000000000000000+0 1.000000000000000-4 + 8.314000000000000+0 2.731500000000000+2 5.000000000000000-1 0.000000000000000+0 5.670510000000000-8 1.438769000000000-2 2.997900000000000+8 1.00000000000000+30 + 0.000000000000000+0 0.000000000000000+0 1.000000000000000+2 0.000000000000000+0 1.000000000000000+0-2.000000000000000+0 1.000000000000000+6 3.000000000000000+0 + 0.000000000000000+0 0.000000000000000+0 1.256637061000000-6 8.85418781700000-12 1.200000000000000+2 1.000000000000000-3 1.600000000000000+2 0.000000000000000+0 + 3.000000000000000+0 4.000000000000000-1 +end option +$................... +$....start of loadcase Tensile +title Tensile +loadcase Tensile + 6 +unten_z +unten_y +oben_z +oben_y +unten_fest +oben_ziehen +control + 99999 10 0 0 0 1 0 0 1 0 0 0 0 0 0 + 1.000000000000000-1 0.000000000000000+0 0.000000000000000+0 0.000000000000000+0 0.000000000000000+0 0.000000000000000+0-1.000000000000000+0 0.000000000000000+0 +parameters + 1.000000000000000+0 1.000000000000000+9 1.000000000000000+2 1.000000000000000+6 2.500000000000000-1 5.000000000000000-1 1.500000000000000+0-5.000000000000000-1 + 8.625000000000000+0 2.000000000000000+1 1.000000000000000-4 1.000000000000000-6 1.000000000000000+0 1.000000000000000-4 + 8.314000000000000+0 2.731500000000000+2 5.000000000000000-1 0.000000000000000+0 5.670510000000000-8 1.438769000000000-2 2.997900000000000+8 1.00000000000000+30 + 0.000000000000000+0 0.000000000000000+0 1.000000000000000+2 0.000000000000000+0 1.000000000000000+0-1.000000000000000+0 1.000000000000000+6 3.000000000000000+0 + 0.000000000000000+0 0.000000000000000+0 1.256637061000000-6 8.85418781700000-12 1.200000000000000+2 1.000000000000000-3 1.600000000000000+2 0.000000000000000+0 + 3.000000000000000+0 4.000000000000000-1 +auto load + 100 0 10 0 0 +time step + 2.000000000000000+0 +continue +$....end of loadcase Tensile +$................... diff --git a/python/damask/solver/_marc.py b/python/damask/solver/_marc.py index 26823911d..9fb07fc1c 100644 --- a/python/damask/solver/_marc.py +++ b/python/damask/solver/_marc.py @@ -1,7 +1,6 @@ import subprocess import shlex import re -import io import os from pathlib import Path @@ -63,7 +62,8 @@ class Marc: ret = subprocess.run(shlex.split(cmd),capture_output=True) try: - if 3004 != int(re.search('Exit number ([0-9]+)',ret.stderr.decode()).group(1)): + v = int(re.search('Exit number ([0-9]+)',ret.stderr.decode()).group(1)) + if 3004 != v: print(ret.stderr.decode()) print(ret.stdout.decode()) raise RuntimeError(f'Marc simulation failed ({v})') From d488f1708a476acb6aa8d7f8fc068eea4192254c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 07:35:43 +0200 Subject: [PATCH 163/219] consistent naming --- src/homogenization.f90 | 2 +- src/homogenization_damage.f90 | 2 +- src/homogenization_thermal.f90 | 7 +++---- src/lattice.f90 | 30 +++++++++++++++--------------- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 34e71a0f2..2408462c9 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -458,7 +458,7 @@ function homogenization_K_phi(ce) do co = 1, homogenization_Nconstituents(ho) homogenization_K_phi = homogenization_K_phi + & - crystallite_push33ToRef(co,ce,lattice_D(1:3,1:3,material_phaseID(co,ce))) + crystallite_push33ToRef(co,ce,lattice_K_phi(1:3,1:3,material_phaseID(co,ce))) enddo homogenization_K_phi = & diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index f0f13bdbb..c7c82331b 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -114,7 +114,7 @@ module function homogenization_mu_phi(ce) result(mu) integer, intent(in) :: ce real(pReal) :: mu - mu = lattice_M(material_phaseID(1,ce)) + mu = lattice_mu_phi(material_phaseID(1,ce)) end function homogenization_mu_phi diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index 8b4eafc3a..eb9f796ce 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -117,10 +117,9 @@ module function homogenization_K_T(ce) result(K) integer :: & co - K = 0.0_pReal - - do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) - K = K + crystallite_push33ToRef(co,ce,lattice_K(:,:,material_phaseID(co,ce))) + K = crystallite_push33ToRef(co,1,lattice_K_T(:,:,material_phaseID(1,ce))) + do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) + K = K + crystallite_push33ToRef(co,ce,lattice_K_T(:,:,material_phaseID(co,ce))) enddo K = K / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) diff --git a/src/lattice.f90 b/src/lattice.f90 index 5ec365fa7..69ee65857 100644 --- a/src/lattice.f90 +++ b/src/lattice.f90 @@ -394,13 +394,13 @@ module lattice ! SHOULD NOT BE PART OF LATTICE BEGIN real(pReal), dimension(:), allocatable, public, protected :: & lattice_mu, lattice_nu, & - lattice_M, & + lattice_mu_phi, & lattice_rho, & lattice_c_p real(pReal), dimension(:,:,:), allocatable, public, protected :: & lattice_C66, & - lattice_K, & - lattice_D + lattice_K_T, & + lattice_K_phi integer(kind(lattice_UNDEFINED_ID)), dimension(:), allocatable, public, protected :: & lattice_structure ! SHOULD NOT BE PART OF LATTICE END @@ -470,10 +470,10 @@ subroutine lattice_init allocate(lattice_structure(Nphases),source = lattice_UNDEFINED_ID) allocate(lattice_C66(6,6,Nphases), source=0.0_pReal) - allocate(lattice_K (3,3,Nphases), source=0.0_pReal) - allocate(lattice_D (3,3,Nphases), source=0.0_pReal) + allocate(lattice_K_T (3,3,Nphases), source=0.0_pReal) + allocate(lattice_K_phi (3,3,Nphases), source=0.0_pReal) - allocate(lattice_M,& + allocate(lattice_mu_phi,& lattice_rho,lattice_c_p, & lattice_mu, lattice_nu,& source=[(0.0_pReal,i=1,Nphases)]) @@ -527,10 +527,10 @@ subroutine lattice_init if (phase%contains('thermal')) then thermal => phase%get('thermal') - lattice_K(1,1,ph) = thermal%get_asFloat('K_11',defaultVal=0.0_pReal) - lattice_K(2,2,ph) = thermal%get_asFloat('K_22',defaultVal=0.0_pReal) - lattice_K(3,3,ph) = thermal%get_asFloat('K_33',defaultVal=0.0_pReal) - lattice_K(1:3,1:3,ph) = lattice_applyLatticeSymmetry33(lattice_K(1:3,1:3,ph), & + lattice_K_T(1,1,ph) = thermal%get_asFloat('K_11',defaultVal=0.0_pReal) + lattice_K_T(2,2,ph) = thermal%get_asFloat('K_22',defaultVal=0.0_pReal) + lattice_K_T(3,3,ph) = thermal%get_asFloat('K_33',defaultVal=0.0_pReal) + lattice_K_T(1:3,1:3,ph) = lattice_applyLatticeSymmetry33(lattice_K_T(1:3,1:3,ph), & phase%get_asString('lattice')) lattice_c_p(ph) = thermal%get_asFloat('c_p', defaultVal=0.0_pReal) endif @@ -539,13 +539,13 @@ subroutine lattice_init if (phase%contains('damage')) then damage => phase%get('damage') damage => damage%get(1) - lattice_D(1,1,ph) = damage%get_asFloat('D_11',defaultVal=0.0_pReal) - lattice_D(2,2,ph) = damage%get_asFloat('D_22',defaultVal=0.0_pReal) - lattice_D(3,3,ph) = damage%get_asFloat('D_33',defaultVal=0.0_pReal) - lattice_D(1:3,1:3,ph) = lattice_applyLatticeSymmetry33(lattice_D(1:3,1:3,ph), & + lattice_K_phi(1,1,ph) = damage%get_asFloat('D_11',defaultVal=0.0_pReal) + lattice_K_phi(2,2,ph) = damage%get_asFloat('D_22',defaultVal=0.0_pReal) + lattice_K_phi(3,3,ph) = damage%get_asFloat('D_33',defaultVal=0.0_pReal) + lattice_K_phi(1:3,1:3,ph) = lattice_applyLatticeSymmetry33(lattice_K_phi(1:3,1:3,ph), & phase%get_asString('lattice')) - lattice_M(ph) = damage%get_asFloat('M',defaultVal=0.0_pReal) + lattice_mu_phi(ph) = damage%get_asFloat('M',defaultVal=0.0_pReal) endif ! SHOULD NOT BE PART OF LATTICE END From a386b82f748c92430fd4f4292bc5802f29cc3639 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 07:48:54 +0200 Subject: [PATCH 164/219] distributing responsibility --- src/homogenization.f90 | 31 +++++-------------------------- src/homogenization_damage.f90 | 15 +++++++++++++++ src/homogenization_thermal.f90 | 1 - 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 2408462c9..195ede741 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -166,6 +166,11 @@ module homogenization real(pReal) :: mu end function homogenization_mu_phi + module function homogenization_K_phi(ce) result(K) + integer, intent(in) :: ce + real(pReal), dimension(3,3) :: K + end function homogenization_K_phi + module function homogenization_f_phi(phi,ce) result(f) integer, intent(in) :: ce real(pReal), intent(in) :: phi @@ -441,32 +446,6 @@ subroutine homogenization_restartRead(fileHandle) end subroutine homogenization_restartRead -!-------------------------------------------------------------------------------------------------- -!> @brief returns homogenized non local damage diffusion tensor in reference configuration -!-------------------------------------------------------------------------------------------------- -function homogenization_K_phi(ce) - - integer, intent(in) :: ce - real(pReal), dimension(3,3) :: & - homogenization_K_phi - integer :: & - ho, & - co - - ho = material_homogenizationID(ce) - homogenization_K_phi = 0.0_pReal - - do co = 1, homogenization_Nconstituents(ho) - homogenization_K_phi = homogenization_K_phi + & - crystallite_push33ToRef(co,ce,lattice_K_phi(1:3,1:3,material_phaseID(co,ce))) - enddo - - homogenization_K_phi = & - num_damage%charLength**2*homogenization_K_phi/real(homogenization_Nconstituents(ho),pReal) - -end function homogenization_K_phi - - !-------------------------------------------------------------------------------------------------- !> @brief parses the homogenization part from the material configuration !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index c7c82331b..79906b8f0 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -154,6 +154,21 @@ module subroutine homogenization_set_phi(phi,ce) end subroutine homogenization_set_phi +!-------------------------------------------------------------------------------------------------- +!> @brief returns homogenized non local damage diffusion tensor in reference configuration +!-------------------------------------------------------------------------------------------------- +module function homogenization_K_phi(ce) result(K) + + integer, intent(in) :: ce + real(pReal), dimension(3,3) :: K + + + K = crystallite_push33ToRef(1,ce,lattice_K_phi(1:3,1:3,material_phaseID(1,ce))) \ + * num_damage%charLength**2 + +end function homogenization_K_phi + + !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index eb9f796ce..6e47d8854 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -229,7 +229,6 @@ module function homogenization_T(ce) result(T) end function homogenization_T - !-------------------------------------------------------------------------------------------------- !> @brief return heat generation rate !-------------------------------------------------------------------------------------------------- From 4b89e2f40cb6955d134bc389cc4926c10ab1f592 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 08:32:13 +0200 Subject: [PATCH 165/219] sorted and documented --- src/homogenization.f90 | 25 +++---- src/homogenization_damage.f90 | 81 +++++++++++----------- src/homogenization_thermal.f90 | 122 +++++++++++++++------------------ 3 files changed, 108 insertions(+), 120 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 195ede741..a1aaff1db 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -135,32 +135,26 @@ module homogenization logical, dimension(2) :: doneAndHappy end function mechanical_updateState + module function homogenization_mu_T(ce) result(mu) + integer, intent(in) :: ce + real(pReal) :: mu + end function homogenization_mu_T module function homogenization_K_T(ce) result(K) integer, intent(in) :: ce real(pReal), dimension(3,3) :: K end function homogenization_K_T - module function homogenization_mu_T(ce) result(mu) + module function homogenization_f_T(ce) result(f) integer, intent(in) :: ce - real(pReal) :: mu - end function homogenization_mu_T + real(pReal) :: f + end function homogenization_f_T module subroutine homogenization_thermal_setField(T,dot_T, ce) integer, intent(in) :: ce real(pReal), intent(in) :: T, dot_T end subroutine homogenization_thermal_setField - module function homogenization_T(ce) result(T) - integer, intent(in) :: ce - real(pReal) :: T - end function homogenization_T - - module function homogenization_f_T(ce) result(f) - integer, intent(in) :: ce - real(pReal) :: f - end function homogenization_f_T - module function homogenization_mu_phi(ce) result(mu) integer, intent(in) :: ce real(pReal) :: mu @@ -191,12 +185,11 @@ module homogenization homogenization_mu_T, & homogenization_K_T, & homogenization_f_T, & - homogenization_K_phi, & + homogenization_thermal_setfield, & homogenization_mu_phi, & + homogenization_K_phi, & homogenization_f_phi, & homogenization_set_phi, & - homogenization_thermal_setfield, & - homogenization_T, & homogenization_forward, & homogenization_results, & homogenization_restartRead, & diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index 79906b8f0..8a4e596a8 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -26,8 +26,8 @@ submodule(homogenization) damage type(tparameters), dimension(:), allocatable :: & param -contains +contains !-------------------------------------------------------------------------------------------------- !> @brief Allocate variables and set parameters. @@ -105,57 +105,22 @@ module subroutine damage_partition(ce) end subroutine damage_partition - !-------------------------------------------------------------------------------------------------- -!> @brief Returns homogenized nonlocal damage mobility +!> @brief Homogenized damage viscosity. !-------------------------------------------------------------------------------------------------- module function homogenization_mu_phi(ce) result(mu) integer, intent(in) :: ce real(pReal) :: mu + mu = lattice_mu_phi(material_phaseID(1,ce)) end function homogenization_mu_phi !-------------------------------------------------------------------------------------------------- -!> @brief calculates homogenized damage driving forces -!-------------------------------------------------------------------------------------------------- -module function homogenization_f_phi(phi,ce) result(f) - - integer, intent(in) :: ce - real(pReal), intent(in) :: & - phi - real(pReal) :: f - - f = phase_f_phi(phi, 1, ce) - -end function homogenization_f_phi - - -!-------------------------------------------------------------------------------------------------- -!> @brief updated nonlocal damage field with solution from damage phase field PDE -!-------------------------------------------------------------------------------------------------- -module subroutine homogenization_set_phi(phi,ce) - - integer, intent(in) :: ce - real(pReal), intent(in) :: & - phi - integer :: & - ho, & - en - - ho = material_homogenizationID(ce) - en = material_homogenizationEntry(ce) - damagestate_h(ho)%state(1,en) = phi - current(ho)%phi(en) = phi - -end subroutine homogenization_set_phi - - -!-------------------------------------------------------------------------------------------------- -!> @brief returns homogenized non local damage diffusion tensor in reference configuration +!> @brief Homogenized damage conductivity/diffusivity in reference configuration. !-------------------------------------------------------------------------------------------------- module function homogenization_K_phi(ce) result(K) @@ -169,6 +134,44 @@ module function homogenization_K_phi(ce) result(K) end function homogenization_K_phi +!-------------------------------------------------------------------------------------------------- +!> @brief Homogenized damage driving force. +!-------------------------------------------------------------------------------------------------- +module function homogenization_f_phi(phi,ce) result(f) + + integer, intent(in) :: ce + real(pReal), intent(in) :: & + phi + real(pReal) :: f + + + f = phase_f_phi(phi, 1, ce) + +end function homogenization_f_phi + + +!-------------------------------------------------------------------------------------------------- +!> @brief Set damage field. +!-------------------------------------------------------------------------------------------------- +module subroutine homogenization_set_phi(phi,ce) + + integer, intent(in) :: ce + real(pReal), intent(in) :: & + phi + + integer :: & + ho, & + en + + + ho = material_homogenizationID(ce) + en = material_homogenizationEntry(ce) + damagestate_h(ho)%state(1,en) = phi + current(ho)%phi(en) = phi + +end subroutine homogenization_set_phi + + !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index 6e47d8854..9c58fc6a8 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -107,15 +107,29 @@ end subroutine thermal_homogenize !-------------------------------------------------------------------------------------------------- -!> @brief return homogenized thermal conductivity in reference configuration +!> @brief Homogenized thermal viscosity. +!-------------------------------------------------------------------------------------------------- +module function homogenization_mu_T(ce) result(mu) + + integer, intent(in) :: ce + real(pReal) :: mu + + + mu = c_P(ce) * rho(ce) + +end function homogenization_mu_T + + +!-------------------------------------------------------------------------------------------------- +!> @brief Homogenized thermal conductivity in reference configuration. !-------------------------------------------------------------------------------------------------- module function homogenization_K_T(ce) result(K) integer, intent(in) :: ce real(pReal), dimension(3,3) :: K - integer :: & - co + integer :: co + K = crystallite_push33ToRef(co,1,lattice_K_T(:,:,material_phaseID(1,ce))) do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) @@ -127,61 +141,29 @@ module function homogenization_K_T(ce) result(K) end function homogenization_K_T -module function homogenization_mu_T(ce) result(mu) +!-------------------------------------------------------------------------------------------------- +!> @brief Homogenized heat generation rate. +!-------------------------------------------------------------------------------------------------- +module function homogenization_f_T(ce) result(f) integer, intent(in) :: ce - real(pReal) :: mu - - mu = c_P(ce) * rho(ce) - -end function homogenization_mu_T - - -!-------------------------------------------------------------------------------------------------- -!> @brief returns homogenized specific heat capacity -!-------------------------------------------------------------------------------------------------- -function c_P(ce) - - integer, intent(in) :: ce - real(pReal) :: c_P + real(pReal) :: f integer :: co - c_P = lattice_c_p(material_phaseID(1,ce)) + f = phase_f_T(material_phaseID(1,ce),material_phaseEntry(1,ce)) do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) - c_P = c_P + lattice_c_p(material_phaseID(co,ce)) + f = f + phase_f_T(material_phaseID(co,ce),material_phaseEntry(co,ce)) enddo - c_P = c_P / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) + f = f/real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) -end function c_P +end function homogenization_f_T !-------------------------------------------------------------------------------------------------- -!> @brief returns homogenized mass density -!-------------------------------------------------------------------------------------------------- -function rho(ce) - - integer, intent(in) :: ce - real(pReal) :: rho - - integer :: co - - - rho = lattice_rho(material_phaseID(1,ce)) - do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) - rho = rho + lattice_rho(material_phaseID(co,ce)) - enddo - - rho = rho / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) - -end function rho - - - -!-------------------------------------------------------------------------------------------------- -!> @brief Set thermal field and its rate (T and dot_T) +!> @brief Set thermal field and its rate (T and dot_T). !-------------------------------------------------------------------------------------------------- module subroutine homogenization_thermal_setField(T,dot_T, ce) @@ -196,7 +178,6 @@ module subroutine homogenization_thermal_setField(T,dot_T, ce) end subroutine homogenization_thermal_setField - !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- @@ -219,34 +200,45 @@ module subroutine thermal_results(ho,group) end subroutine thermal_results -module function homogenization_T(ce) result(T) +!-------------------------------------------------------------------------------------------------- +!> @brief Homogenize specific heat capacity. +!-------------------------------------------------------------------------------------------------- +function c_P(ce) integer, intent(in) :: ce - real(pReal) :: T - - T = current(material_homogenizationID(ce))%T(material_homogenizationEntry(ce)) - -end function homogenization_T - - -!-------------------------------------------------------------------------------------------------- -!> @brief return heat generation rate -!-------------------------------------------------------------------------------------------------- -module function homogenization_f_T(ce) result(f) - - integer, intent(in) :: ce - real(pReal) :: f + real(pReal) :: c_P integer :: co - f = phase_f_T(material_phaseID(1,ce),material_phaseEntry(1,ce)) + + c_P = lattice_c_p(material_phaseID(1,ce)) do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) - f = f + phase_f_T(material_phaseID(co,ce),material_phaseEntry(co,ce)) + c_P = c_P + lattice_c_p(material_phaseID(co,ce)) enddo - f = f/real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) + c_P = c_P / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) -end function homogenization_f_T +end function c_P +!-------------------------------------------------------------------------------------------------- +!> @brief Homogenize mass density. +!-------------------------------------------------------------------------------------------------- +function rho(ce) + + integer, intent(in) :: ce + real(pReal) :: rho + + integer :: co + + + rho = lattice_rho(material_phaseID(1,ce)) + do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) + rho = rho + lattice_rho(material_phaseID(co,ce)) + enddo + + rho = rho / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) + +end function rho + end submodule thermal From 34bb4c65a9b5b95732969bbb287c1a900ab4c546 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 08:46:31 +0200 Subject: [PATCH 166/219] distributing responsibility --- src/phase_damage.f90 | 14 +++++++++++++- src/phase_thermal.f90 | 11 +++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index 189a5eabf..c0c0768e7 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -2,6 +2,12 @@ !> @brief internal microstructure state for all damage sources and kinematics constitutive models !---------------------------------------------------------------------------------------------------- submodule(phase) damage + + type :: tDamageParameters + real(pReal) :: mu = 0.0_pReal !< viscosity + real(pReal), dimension(3,3) :: K = 0.0_pReal !< conductivity/diffusivity + end type tDamageParameters + enum, bind(c); enumerator :: & DAMAGE_UNDEFINED_ID, & DAMAGE_ISOBRITTLE_ID, & @@ -16,13 +22,15 @@ submodule(phase) damage end type tDataContainer integer(kind(DAMAGE_UNDEFINED_ID)), dimension(:), allocatable :: & - phase_source !< active sources mechanisms of each phase + phase_source !< active sources mechanisms of each phase integer, dimension(:), allocatable :: & phase_Nsources type(tDataContainer), dimension(:), allocatable :: current + type(tDamageParameters), dimension(:), allocatable :: param + interface module function anisobrittle_init() result(mySources) @@ -111,6 +119,7 @@ module subroutine damage_init allocate(damageState (phases%length)) allocate(phase_Nsources(phases%length),source = 0) + allocate(param(phases%length)) do ph = 1,phases%length @@ -121,6 +130,9 @@ module subroutine damage_init phase => phases%get(ph) sources => phase%get('damage',defaultVal=emptyList) + param(ph)%K(1,1) = sources%get_asFloat('K_11',defaultVal=0.0_pReal) + param(ph)%K(2,2) = sources%get_asFloat('K_22',defaultVal=0.0_pReal) + param(ph)%K(3,3) = sources%get_asFloat('K_33',defaultVal=0.0_pReal) if (sources%length > 1) error stop phase_Nsources(ph) = sources%length diff --git a/src/phase_thermal.f90 b/src/phase_thermal.f90 index 807e1f655..c2b4b34b2 100644 --- a/src/phase_thermal.f90 +++ b/src/phase_thermal.f90 @@ -3,6 +3,11 @@ !---------------------------------------------------------------------------------------------------- submodule(phase) thermal + type :: tThermalParameters + real(pReal) :: C_p = 0.0_pReal !< heat capacity + real(pReal), dimension(3,3) :: K = 0.0_pReal !< thermal conductivity + end type tThermalParameters + integer, dimension(:), allocatable :: & thermal_Nsources @@ -23,6 +28,8 @@ submodule(phase) thermal type(tDataContainer), dimension(:), allocatable :: current ! ?? not very telling name. Better: "field" ?? MD: current(ho)%T(me) reads quite good + type(tThermalParameters), dimension(:), allocatable :: param + integer :: thermal_source_maxSizeDotState @@ -85,6 +92,7 @@ module subroutine thermal_init(phases) allocate(thermalState(phases%length)) allocate(thermal_Nsources(phases%length),source = 0) + allocate(param(phases%length)) do ph = 1, phases%length Nmembers = count(material_phaseID == ph) @@ -93,6 +101,9 @@ module subroutine thermal_init(phases) phase => phases%get(ph) thermal => phase%get('thermal',defaultVal=emptyDict) sources => thermal%get('source',defaultVal=emptyList) + param(ph)%K(1,1) = thermal%get_asFloat('K_11',defaultVal=0.0_pReal) + param(ph)%K(2,2) = thermal%get_asFloat('K_22',defaultVal=0.0_pReal) + param(ph)%K(3,3) = thermal%get_asFloat('K_33',defaultVal=0.0_pReal) thermal_Nsources(ph) = sources%length allocate(thermalstate(ph)%p(thermal_Nsources(ph))) enddo From b55e721ec486e34d34de493e6625cd638ae410c9 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 09:25:45 +0200 Subject: [PATCH 167/219] standard name --- src/CPFEM.f90 | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index 60dc78d2e..d8f4a0c3c 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -150,15 +150,14 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS H integer(pInt) elCP, & ! crystal plasticity element number - i, j, k, l, m, n, ph, homog, mySource,ma + i, j, k, l, m, n, ph, homog, mySource,ce real(pReal), parameter :: ODD_STRESS = 1e15_pReal, & !< return value for stress if terminallyIll ODD_JACOBIAN = 1e50_pReal !< return value for jacobian if terminallyIll elCP = discretization_Marc_FEM2DAMASK_elem(elFE) - - ma = (elCP-1) * discretization_nIPs + ip + ce = discretization_Marc_FEM2DAMASK_cell(ip,elFE) if (debugCPFEM%basic .and. elCP == debugCPFEM%element .and. ip == debugCPFEM%ip) then print'(/,a)', '#############################################' @@ -183,8 +182,8 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS ! temperature(material_homogenizationAt(elCP))%p(material_homogenizationMemberAt(ip,elCP)) = & ! temperature_inp !end select chosenThermal1 - homogenization_F0(1:3,1:3,ma) = ffn - homogenization_F(1:3,1:3,ma) = ffn1 + homogenization_F0(1:3,1:3,ce) = ffn + homogenization_F(1:3,1:3,ce) = ffn1 if (iand(mode, CPFEM_CALCRESULTS) /= 0_pInt) then @@ -209,17 +208,17 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS else terminalIllness ! translate from P to sigma - Kirchhoff = matmul(homogenization_P(1:3,1:3,ma), transpose(homogenization_F(1:3,1:3,ma))) - J_inverse = 1.0_pReal / math_det33(homogenization_F(1:3,1:3,ma)) + Kirchhoff = matmul(homogenization_P(1:3,1:3,ce), transpose(homogenization_F(1:3,1:3,ce))) + J_inverse = 1.0_pReal / math_det33(homogenization_F(1:3,1:3,ce)) CPFEM_cs(1:6,ip,elCP) = math_sym33to6(J_inverse * Kirchhoff,weighted=.false.) ! translate from dP/dF to dCS/dE H = 0.0_pReal do i=1,3; do j=1,3; do k=1,3; do l=1,3; do m=1,3; do n=1,3 H(i,j,k,l) = H(i,j,k,l) & - + homogenization_F(j,m,ma) * homogenization_F(l,n,ma) & - * homogenization_dPdF(i,m,k,n,ma) & - - math_delta(j,l) * homogenization_F(i,m,ma) * homogenization_P(k,m,ma) & + + homogenization_F(j,m,ce) * homogenization_F(l,n,ce) & + * homogenization_dPdF(i,m,k,n,ce) & + - math_delta(j,l) * homogenization_F(i,m,ce) * homogenization_P(k,m,ce) & + 0.5_pReal * ( Kirchhoff(j,l)*math_delta(i,k) + Kirchhoff(i,k)*math_delta(j,l) & + Kirchhoff(j,k)*math_delta(i,l) + Kirchhoff(i,l)*math_delta(j,k)) enddo; enddo; enddo; enddo; enddo; enddo From 547f2ffa69fcb2b2548968d37189f74de1f113c6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 09:46:11 +0200 Subject: [PATCH 168/219] cleaning --- src/DAMASK_Marc.f90 | 3 +-- src/grid/discretization_grid.f90 | 2 +- src/grid/grid_damage_spectral.f90 | 14 ++++++-------- src/grid/grid_thermal_spectral.f90 | 10 +++++----- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/DAMASK_Marc.f90 b/src/DAMASK_Marc.f90 index 43ec9b084..910ca86c0 100644 --- a/src/DAMASK_Marc.f90 +++ b/src/DAMASK_Marc.f90 @@ -218,7 +218,7 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, & logical :: cutBack real(pReal), dimension(6) :: stress real(pReal), dimension(6,6) :: ddsdde - integer :: computationMode, i, cp_en, node, CPnodeID + integer :: computationMode, i, node, CPnodeID integer(pI32) :: defaultNumThreadsInt !< default value set by Marc integer(pInt), save :: & @@ -266,7 +266,6 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, & computationMode = CPFEM_RESTOREJACOBIAN elseif (lovl == 6) then ! stress requested by marc computationMode = CPFEM_CALCRESULTS - cp_en = discretization_Marc_FEM2DAMASK_elem(m(1)) if (cptim > theTime .or. inc /= theInc) then ! reached "convergence" terminallyIll = .false. cycleCounter = -1 ! first calc step increments this to cycle = 0 diff --git a/src/grid/discretization_grid.f90 b/src/grid/discretization_grid.f90 index 88216f0aa..14391fd23 100644 --- a/src/grid/discretization_grid.f90 +++ b/src/grid/discretization_grid.f90 @@ -74,7 +74,7 @@ subroutine discretization_grid_init(restart) allocate(materialAt_global(0)) ! needed for IntelMPI endif - if (grid(1) < 2) call IO_error(844, ext_msg='cells(1) must be larger than 1') + if (grid(1) < 2) call IO_error(844, ext_msg='cells(1) must be larger than 1') call MPI_Bcast(grid,3,MPI_INTEGER,0,PETSC_COMM_WORLD, ierr) if (ierr /= 0) error stop 'MPI error' diff --git a/src/grid/grid_damage_spectral.f90 b/src/grid/grid_damage_spectral.f90 index 7e0d4112a..7fe9a4a25 100644 --- a/src/grid/grid_damage_spectral.f90 +++ b/src/grid/grid_damage_spectral.f90 @@ -259,7 +259,6 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) PetscObject :: dummy PetscErrorCode :: ierr integer :: i, j, k, ce - real(pReal) :: mobility phi_current = x_scal !-------------------------------------------------------------------------------------------------- @@ -281,9 +280,8 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) ce = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - mobility = homogenization_mu_phi(ce) scalarField_real(i,j,k) = params%timeinc*(scalarField_real(i,j,k) + homogenization_f_phi(phi_current(i,j,k),ce)) & - + mobility*(phi_lastInc(i,j,k) - phi_current(i,j,k)) & + + homogenization_mu_phi(ce)*(phi_lastInc(i,j,k) - phi_current(i,j,k)) & + mu_ref*phi_current(i,j,k) enddo; enddo; enddo @@ -309,16 +307,16 @@ end subroutine formResidual !-------------------------------------------------------------------------------------------------- subroutine updateReference - integer :: i,j,k,ce,ierr + integer :: ce,ierr + - ce = 0 K_ref = 0.0_pReal mu_ref = 0.0_pReal - do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) - ce = ce + 1 + do ce = 1, product(grid(1:2))*grid3 K_ref = K_ref + homogenization_K_phi(ce) mu_ref = mu_ref + homogenization_mu_phi(ce) - enddo; enddo; enddo + enddo + K_ref = K_ref*wgt call MPI_Allreduce(MPI_IN_PLACE,K_ref,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr) mu_ref = mu_ref*wgt diff --git a/src/grid/grid_thermal_spectral.f90 b/src/grid/grid_thermal_spectral.f90 index ea6caec0e..60d8d99db 100644 --- a/src/grid/grid_thermal_spectral.f90 +++ b/src/grid/grid_thermal_spectral.f90 @@ -302,16 +302,16 @@ end subroutine formResidual !-------------------------------------------------------------------------------------------------- subroutine updateReference - integer :: i,j,k,ce,ierr + integer :: ce,ierr + - ce = 0 K_ref = 0.0_pReal mu_ref = 0.0_pReal - do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) - ce = ce + 1 + do ce = 1, product(grid(1:2))*grid3 K_ref = K_ref + homogenization_K_T(ce) mu_ref = mu_ref + homogenization_mu_T(ce) - enddo; enddo; enddo + enddo + K_ref = K_ref*wgt call MPI_Allreduce(MPI_IN_PLACE,K_ref,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr) mu_ref = mu_ref*wgt From b67e8375483a351d548ad9c9f4410cad6fc14981 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 09:58:40 +0200 Subject: [PATCH 169/219] needs broadcast, otherwise rank>0 fail --- src/grid/discretization_grid.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/grid/discretization_grid.f90 b/src/grid/discretization_grid.f90 index 14391fd23..ad614d8c5 100644 --- a/src/grid/discretization_grid.f90 +++ b/src/grid/discretization_grid.f90 @@ -74,10 +74,10 @@ subroutine discretization_grid_init(restart) allocate(materialAt_global(0)) ! needed for IntelMPI endif - if (grid(1) < 2) call IO_error(844, ext_msg='cells(1) must be larger than 1') call MPI_Bcast(grid,3,MPI_INTEGER,0,PETSC_COMM_WORLD, ierr) if (ierr /= 0) error stop 'MPI error' + if (grid(1) < 2) call IO_error(844, ext_msg='cells(1) must be larger than 1') call MPI_Bcast(geomSize,3,MPI_DOUBLE,0,PETSC_COMM_WORLD, ierr) if (ierr /= 0) error stop 'MPI error' call MPI_Bcast(origin,3,MPI_DOUBLE,0,PETSC_COMM_WORLD, ierr) From 8b7f77718627c88789802838a0690fc5a0d333e8 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 11:17:52 +0200 Subject: [PATCH 170/219] probably not needed --- src/homogenization.f90 | 5 ----- src/homogenization_thermal.f90 | 12 ------------ 2 files changed, 17 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index a1aaff1db..3fadf1e96 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -100,10 +100,6 @@ module homogenization integer, intent(in) :: ce end subroutine damage_partition - module subroutine thermal_homogenize(ip,el) - integer, intent(in) :: ip,el - end subroutine thermal_homogenize - module subroutine mechanical_homogenize(dt,ce) real(pReal), intent(in) :: dt integer, intent(in) :: & @@ -306,7 +302,6 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE terminallyIll = .true. ! ...and kills all others endif enddo - call thermal_homogenize(ip,el) enddo enddo !$OMP END DO diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index 9c58fc6a8..40c466ab5 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -94,18 +94,6 @@ module subroutine thermal_partition(ce) end subroutine thermal_partition -!-------------------------------------------------------------------------------------------------- -!> @brief Homogenize temperature rates -!-------------------------------------------------------------------------------------------------- -module subroutine thermal_homogenize(ip,el) - - integer, intent(in) :: ip,el - - !call phase_thermal_getRate(homogenization_dot_T((el-1)*discretization_nIPs+ip), ip,el) - -end subroutine thermal_homogenize - - !-------------------------------------------------------------------------------------------------- !> @brief Homogenized thermal viscosity. !-------------------------------------------------------------------------------------------------- From 071c1a5ad453f21d2ba56716147f25a3fa9ea81f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 12:18:26 +0200 Subject: [PATCH 171/219] avoid repetition --- src/homogenization_mechanical.f90 | 61 +++------------ src/homogenization_mechanical_RGC.f90 | 25 +------ src/homogenization_mechanical_isostrain.f90 | 83 +++------------------ src/homogenization_mechanical_pass.f90 | 21 +++--- 4 files changed, 36 insertions(+), 154 deletions(-) diff --git a/src/homogenization_mechanical.f90 b/src/homogenization_mechanical.f90 index 7d1c64445..7ea1f74e9 100644 --- a/src/homogenization_mechanical.f90 +++ b/src/homogenization_mechanical.f90 @@ -32,25 +32,6 @@ submodule(homogenization) mechanical end subroutine RGC_partitionDeformation - module subroutine isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho) - real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point - real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point - - real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses - real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses - integer, intent(in) :: ho - end subroutine isostrain_averageStressAndItsTangent - - module subroutine RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho) - real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point - real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point - - real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses - real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses - integer, intent(in) :: ho - end subroutine RGC_averageStressAndItsTangent - - module function RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHappy) logical, dimension(2) :: doneAndHappy real(pReal), dimension(:,:,:), intent(in) :: & @@ -148,39 +129,21 @@ module subroutine mechanical_homogenize(dt,ce) integer, intent(in) :: ce integer :: co - real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationID(ce))) - real(pReal) :: Ps(3,3,homogenization_Nconstituents(material_homogenizationID(ce))) - chosenHomogenization: select case(homogenization_type(material_homogenizationID(ce))) + homogenization_P(1:3,1:3,ce) = phase_P(1,ce) + homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = phase_mechanical_dPdF(dt,1,ce) + do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) + homogenization_P(1:3,1:3,ce) = homogenization_P(1:3,1:3,ce) & + + phase_P(co,ce) + homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = homogenization_dPdF(1:3,1:3,1:3,1:3,ce) & + + phase_mechanical_dPdF(dt,co,ce) + enddo - case (HOMOGENIZATION_NONE_ID) chosenHomogenization - homogenization_P(1:3,1:3,ce) = phase_P(1,ce) - homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = phase_mechanical_dPdF(dt,1,ce) - - case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization - do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) - dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(dt,co,ce) - Ps(:,:,co) = phase_P(co,ce) - enddo - call isostrain_averageStressAndItsTangent(& - homogenization_P(1:3,1:3,ce), & - homogenization_dPdF(1:3,1:3,1:3,1:3,ce),& - Ps,dPdFs, & - material_homogenizationID(ce)) - - case (HOMOGENIZATION_RGC_ID) chosenHomogenization - do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) - dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(dt,co,ce) - Ps(:,:,co) = phase_P(co,ce) - enddo - call RGC_averageStressAndItsTangent(& - homogenization_P(1:3,1:3,ce), & - homogenization_dPdF(1:3,1:3,1:3,1:3,ce),& - Ps,dPdFs, & - material_homogenizationID(ce)) - - end select chosenHomogenization + homogenization_P(1:3,1:3,ce) = homogenization_P(1:3,1:3,ce) & + / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) + homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = homogenization_dPdF(1:3,1:3,1:3,1:3,ce) & + / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) end subroutine mechanical_homogenize diff --git a/src/homogenization_mechanical_RGC.f90 b/src/homogenization_mechanical_RGC.f90 index 772d1c4f5..745c266d4 100644 --- a/src/homogenization_mechanical_RGC.f90 +++ b/src/homogenization_mechanical_RGC.f90 @@ -89,7 +89,8 @@ module subroutine RGC_init(num_homogMech) print'(/,a)', ' <<<+- homogenization:mechanical:RGC init -+>>>' - print'(a,i2)', ' # instances: ',count(homogenization_type == HOMOGENIZATION_RGC_ID); flush(IO_STDOUT) + print'(a,i2)', ' # instances: ',count(homogenization_type == HOMOGENIZATION_RGC_ID) + flush(IO_STDOUT) print*, 'D.D. Tjahjanto et al., International Journal of Material Forming 2(1):939–942, 2009' print*, 'https://doi.org/10.1007/s12289-009-0619-1'//IO_EOL @@ -207,7 +208,7 @@ module subroutine RGC_partitionDeformation(F,avgF,ce) integer :: iGrain,iFace,i,j,ho,en associate(prm => param(material_homogenizationID(ce))) - + ho = material_homogenizationID(ce) en = material_homogenizationEntry(ce) !-------------------------------------------------------------------------------------------------- @@ -700,24 +701,6 @@ module function RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHappy) end function RGC_updateState -!-------------------------------------------------------------------------------------------------- -!> @brief derive average stress and stiffness from constituent quantities -!-------------------------------------------------------------------------------------------------- -module subroutine RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho) - - real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point - real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point - - real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses - real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses - integer, intent(in) :: ho - - avgP = sum(P,3) /real(product(param(ho)%N_constituents),pReal) - dAvgPdAvgF = sum(dPdF,5)/real(product(param(ho)%N_constituents),pReal) - -end subroutine RGC_averageStressAndItsTangent - - !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- @@ -802,7 +785,7 @@ pure function interfaceNormal(intFace,ho,en) interfaceNormal(nPos) = real(intFace(1)/abs(intFace(1)),pReal) ! get the normal vector w.r.t. cluster axis interfaceNormal = matmul(dst%orientation(1:3,1:3,en),interfaceNormal) ! map the normal vector into sample coordinate system (basis) - + end associate end function interfaceNormal diff --git a/src/homogenization_mechanical_isostrain.f90 b/src/homogenization_mechanical_isostrain.f90 index 9a3704575..7b114d04f 100644 --- a/src/homogenization_mechanical_isostrain.f90 +++ b/src/homogenization_mechanical_isostrain.f90 @@ -6,21 +6,6 @@ !-------------------------------------------------------------------------------------------------- submodule(homogenization:mechanical) isostrain - enum, bind(c); enumerator :: & - parallel_ID, & - average_ID - end enum - - type :: tParameters !< container type for internal constitutive parameters - integer :: & - N_constituents - integer(kind(average_ID)) :: & - mapping - end type - - type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstances) - - contains !-------------------------------------------------------------------------------------------------- @@ -29,42 +14,21 @@ contains module subroutine isostrain_init integer :: & - h, & + ho, & Nmaterialpoints - class(tNode), pointer :: & - material_homogenization, & - homog, & - homogMech print'(/,a)', ' <<<+- homogenization:mechanical:isostrain init -+>>>' - print'(a,i2)', ' # instances: ',count(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID); flush(IO_STDOUT) + print'(a,i2)', ' # instances: ',count(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID) + flush(IO_STDOUT) - material_homogenization => config_material%get('homogenization') - allocate(param(material_homogenization%length)) ! one container of parameters per homog + do ho = 1, size(homogenization_type) + if (homogenization_type(ho) /= HOMOGENIZATION_ISOSTRAIN_ID) cycle - do h = 1, size(homogenization_type) - if (homogenization_type(h) /= HOMOGENIZATION_ISOSTRAIN_ID) cycle - homog => material_homogenization%get(h) - homogMech => homog%get('mechanical') - associate(prm => param(h)) - - prm%N_constituents = homogenization_Nconstituents(h) - select case(homogMech%get_asString('mapping',defaultVal = 'sum')) - case ('sum') - prm%mapping = parallel_ID - case ('avg') - prm%mapping = average_ID - case default - call IO_error(211,ext_msg='sum'//' (isostrain)') - end select - - Nmaterialpoints = count(material_homogenizationAt == h) - homogState(h)%sizeState = 0 - allocate(homogState(h)%state0 (0,Nmaterialpoints)) - allocate(homogState(h)%state (0,Nmaterialpoints)) - - end associate + Nmaterialpoints = count(material_homogenizationAt == ho) + homogState(ho)%sizeState = 0 + allocate(homogState(ho)%state0(0,Nmaterialpoints)) + allocate(homogState(ho)%state (0,Nmaterialpoints)) enddo @@ -80,36 +44,9 @@ module subroutine isostrain_partitionDeformation(F,avgF) real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point + F = spread(avgF,3,size(F,3)) end subroutine isostrain_partitionDeformation - -!-------------------------------------------------------------------------------------------------- -!> @brief derive average stress and stiffness from constituent quantities -!-------------------------------------------------------------------------------------------------- -module subroutine isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho) - - real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point - real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point - - real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses - real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses - integer, intent(in) :: ho - - associate(prm => param(ho)) - - select case (prm%mapping) - case (parallel_ID) - avgP = sum(P,3) - dAvgPdAvgF = sum(dPdF,5) - case (average_ID) - avgP = sum(P,3) /real(prm%N_constituents,pReal) - dAvgPdAvgF = sum(dPdF,5)/real(prm%N_constituents,pReal) - end select - - end associate - -end subroutine isostrain_averageStressAndItsTangent - end submodule isostrain diff --git a/src/homogenization_mechanical_pass.f90 b/src/homogenization_mechanical_pass.f90 index 23fe74f44..e2e44658a 100644 --- a/src/homogenization_mechanical_pass.f90 +++ b/src/homogenization_mechanical_pass.f90 @@ -14,25 +14,24 @@ contains module subroutine pass_init integer :: & - Ninstances, & - h, & + ho, & Nmaterialpoints print'(/,a)', ' <<<+- homogenization:mechanical:pass init -+>>>' - Ninstances = count(homogenization_type == HOMOGENIZATION_NONE_ID) - print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT) + print'(a,i2)', ' # instances: ',count(homogenization_type == HOMOGENIZATION_NONE_ID) + flush(IO_STDOUT) - do h = 1, size(homogenization_type) - if(homogenization_type(h) /= HOMOGENIZATION_NONE_ID) cycle + do ho = 1, size(homogenization_type) + if(homogenization_type(ho) /= HOMOGENIZATION_NONE_ID) cycle - if(homogenization_Nconstituents(h) /= 1) & + if(homogenization_Nconstituents(ho) /= 1) & call IO_error(211,ext_msg='N_constituents (pass)') - Nmaterialpoints = count(material_homogenizationAt == h) - homogState(h)%sizeState = 0 - allocate(homogState(h)%state0 (0,Nmaterialpoints)) - allocate(homogState(h)%state (0,Nmaterialpoints)) + Nmaterialpoints = count(material_homogenizationAt == ho) + homogState(ho)%sizeState = 0 + allocate(homogState(ho)%state0(0,Nmaterialpoints)) + allocate(homogState(ho)%state (0,Nmaterialpoints)) enddo From 081d51f224d64e65a8628d7d375ac29529746f6c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 12:37:46 +0200 Subject: [PATCH 172/219] multiple damage mechanisms currently not supported --- src/phase_damage.f90 | 59 +++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 34 deletions(-) diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index c0c0768e7..51a3ddac5 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -24,9 +24,6 @@ submodule(phase) damage integer(kind(DAMAGE_UNDEFINED_ID)), dimension(:), allocatable :: & phase_source !< active sources mechanisms of each phase - integer, dimension(:), allocatable :: & - phase_Nsources - type(tDataContainer), dimension(:), allocatable :: current type(tDamageParameters), dimension(:), allocatable :: param @@ -109,7 +106,7 @@ module subroutine damage_init phases, & phase, & sources - + logical:: damage_active print'(/,a)', ' <<<+- phase:damage init -+>>>' @@ -118,9 +115,9 @@ module subroutine damage_init allocate(current(phases%length)) allocate(damageState (phases%length)) - allocate(phase_Nsources(phases%length),source = 0) allocate(param(phases%length)) + damage_active = .false. do ph = 1,phases%length Nmembers = count(material_phaseID == ph) @@ -134,14 +131,13 @@ module subroutine damage_init param(ph)%K(2,2) = sources%get_asFloat('K_22',defaultVal=0.0_pReal) param(ph)%K(3,3) = sources%get_asFloat('K_33',defaultVal=0.0_pReal) if (sources%length > 1) error stop - phase_Nsources(ph) = sources%length + if (sources%length == 1) damage_active = .true. enddo allocate(phase_source(phases%length), source = DAMAGE_UNDEFINED_ID) -! initialize source mechanisms - if(maxval(phase_Nsources) /= 0) then + if (damage_active) then where(isobrittle_init() ) phase_source = DAMAGE_ISOBRITTLE_ID where(isoductile_init() ) phase_source = DAMAGE_ISODUCTILE_ID where(anisobrittle_init()) phase_source = DAMAGE_ANISOBRITTLE_ID @@ -288,30 +284,25 @@ module subroutine damage_results(group,ph) character(len=*), intent(in) :: group integer, intent(in) :: ph - integer :: so - - sourceLoop: do so = 1, phase_Nsources(ph) if (phase_source(ph) /= DAMAGE_UNDEFINED_ID) & call results_closeGroup(results_addGroup(group//'damage')) - sourceType: select case (phase_source(ph)) + sourceType: select case (phase_source(ph)) - case (DAMAGE_ISOBRITTLE_ID) sourceType - call isobrittle_results(ph,group//'damage/') + case (DAMAGE_ISOBRITTLE_ID) sourceType + call isobrittle_results(ph,group//'damage/') - case (DAMAGE_ISODUCTILE_ID) sourceType - call isoductile_results(ph,group//'damage/') + case (DAMAGE_ISODUCTILE_ID) sourceType + call isoductile_results(ph,group//'damage/') - case (DAMAGE_ANISOBRITTLE_ID) sourceType - call anisobrittle_results(ph,group//'damage/') + case (DAMAGE_ANISOBRITTLE_ID) sourceType + call anisobrittle_results(ph,group//'damage/') - case (DAMAGE_ANISODUCTILE_ID) sourceType - call anisoductile_results(ph,group//'damage/') + case (DAMAGE_ANISODUCTILE_ID) sourceType + call anisoductile_results(ph,group//'damage/') - end select sourceType - - enddo SourceLoop + end select sourceType end subroutine damage_results @@ -374,19 +365,19 @@ function phase_damage_deltaState(Fe, ph, me) result(broken) if (damageState(ph)%sizeState == 0) return - sourceType: select case (phase_source(ph)) + sourceType: select case (phase_source(ph)) - case (DAMAGE_ISOBRITTLE_ID) sourceType - call isobrittle_deltaState(phase_homogenizedC(ph,me), Fe, ph,me) - broken = any(IEEE_is_NaN(damageState(ph)%deltaState(:,me))) - if(.not. broken) then - myOffset = damageState(ph)%offsetDeltaState - mySize = damageState(ph)%sizeDeltaState - damageState(ph)%state(myOffset + 1: myOffset + mySize,me) = & - damageState(ph)%state(myOffset + 1: myOffset + mySize,me) + damageState(ph)%deltaState(1:mySize,me) - endif + case (DAMAGE_ISOBRITTLE_ID) sourceType + call isobrittle_deltaState(phase_homogenizedC(ph,me), Fe, ph,me) + broken = any(IEEE_is_NaN(damageState(ph)%deltaState(:,me))) + if(.not. broken) then + myOffset = damageState(ph)%offsetDeltaState + mySize = damageState(ph)%sizeDeltaState + damageState(ph)%state(myOffset + 1: myOffset + mySize,me) = & + damageState(ph)%state(myOffset + 1: myOffset + mySize,me) + damageState(ph)%deltaState(1:mySize,me) + endif - end select sourceType + end select sourceType end function phase_damage_deltaState From 9d90ed525e442f4a843db05cf22be33f30ae6ea9 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 12:42:57 +0200 Subject: [PATCH 173/219] YAML structure allows more than one mechanism --- src/phase_damage.f90 | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index 51a3ddac5..5f6d65ab8 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -105,7 +105,8 @@ module subroutine damage_init class(tNode), pointer :: & phases, & phase, & - sources + sources, & + source logical:: damage_active print'(/,a)', ' <<<+- phase:damage init -+>>>' @@ -113,7 +114,6 @@ module subroutine damage_init phases => config_material%get('phase') allocate(current(phases%length)) - allocate(damageState (phases%length)) allocate(param(phases%length)) @@ -127,11 +127,14 @@ module subroutine damage_init phase => phases%get(ph) sources => phase%get('damage',defaultVal=emptyList) - param(ph)%K(1,1) = sources%get_asFloat('K_11',defaultVal=0.0_pReal) - param(ph)%K(2,2) = sources%get_asFloat('K_22',defaultVal=0.0_pReal) - param(ph)%K(3,3) = sources%get_asFloat('K_33',defaultVal=0.0_pReal) if (sources%length > 1) error stop - if (sources%length == 1) damage_active = .true. + if (sources%length == 1) then + damage_active = .true. + source => sources%get(1) + param(ph)%K(1,1) = source%get_asFloat('K_11',defaultVal=0.0_pReal) + param(ph)%K(2,2) = source%get_asFloat('K_22',defaultVal=0.0_pReal) + param(ph)%K(3,3) = source%get_asFloat('K_33',defaultVal=0.0_pReal) + endif enddo From 8ec2d3a9ced292501d5ad16adea143bd15ede788 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 12:49:28 +0200 Subject: [PATCH 174/219] bugfix: mixed up order --- src/homogenization_thermal.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index 40c466ab5..27988dfb2 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -119,7 +119,7 @@ module function homogenization_K_T(ce) result(K) integer :: co - K = crystallite_push33ToRef(co,1,lattice_K_T(:,:,material_phaseID(1,ce))) + K = crystallite_push33ToRef(1,ce,lattice_K_T(:,:,material_phaseID(1,ce))) do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) K = K + crystallite_push33ToRef(co,ce,lattice_K_T(:,:,material_phaseID(co,ce))) enddo From b2292986f472777cc7552e49e156c778a5ad78b2 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 13:21:27 +0200 Subject: [PATCH 175/219] distributing responsibilities --- src/homogenization_damage.f90 | 4 +-- src/homogenization_thermal.f90 | 55 +++++++--------------------------- src/phase.f90 | 28 ++++++++++++++++- src/phase_damage.f90 | 27 +++++++++++++++++ src/phase_thermal.f90 | 29 ++++++++++++++++++ 5 files changed, 95 insertions(+), 48 deletions(-) diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index 8a4e596a8..b8aecccae 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -114,7 +114,7 @@ module function homogenization_mu_phi(ce) result(mu) real(pReal) :: mu - mu = lattice_mu_phi(material_phaseID(1,ce)) + mu = phase_mu_phi(1,ce) end function homogenization_mu_phi @@ -128,7 +128,7 @@ module function homogenization_K_phi(ce) result(K) real(pReal), dimension(3,3) :: K - K = crystallite_push33ToRef(1,ce,lattice_K_phi(1:3,1:3,material_phaseID(1,ce))) \ + K = phase_K_phi(1,ce) & * num_damage%charLength**2 end function homogenization_K_phi diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index 27988dfb2..0effe09ed 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -102,8 +102,15 @@ module function homogenization_mu_T(ce) result(mu) integer, intent(in) :: ce real(pReal) :: mu + integer :: co - mu = c_P(ce) * rho(ce) + + mu = phase_mu_T(1,ce) + do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) + mu = mu + phase_mu_T(co,ce) + enddo + + mu = mu / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) end function homogenization_mu_T @@ -119,9 +126,9 @@ module function homogenization_K_T(ce) result(K) integer :: co - K = crystallite_push33ToRef(1,ce,lattice_K_T(:,:,material_phaseID(1,ce))) + K = phase_K_T(1,ce) do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) - K = K + crystallite_push33ToRef(co,ce,lattice_K_T(:,:,material_phaseID(co,ce))) + K = K + phase_K_T(co,ce) enddo K = K / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) @@ -187,46 +194,4 @@ module subroutine thermal_results(ho,group) end subroutine thermal_results - -!-------------------------------------------------------------------------------------------------- -!> @brief Homogenize specific heat capacity. -!-------------------------------------------------------------------------------------------------- -function c_P(ce) - - integer, intent(in) :: ce - real(pReal) :: c_P - - integer :: co - - - c_P = lattice_c_p(material_phaseID(1,ce)) - do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) - c_P = c_P + lattice_c_p(material_phaseID(co,ce)) - enddo - - c_P = c_P / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) - -end function c_P - - -!-------------------------------------------------------------------------------------------------- -!> @brief Homogenize mass density. -!-------------------------------------------------------------------------------------------------- -function rho(ce) - - integer, intent(in) :: ce - real(pReal) :: rho - - integer :: co - - - rho = lattice_rho(material_phaseID(1,ce)) - do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) - rho = rho + lattice_rho(material_phaseID(co,ce)) - enddo - - rho = rho / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) - -end function rho - end submodule thermal diff --git a/src/phase.f90 b/src/phase.f90 index 346772ce4..54116f3c9 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -184,7 +184,7 @@ module phase module subroutine phase_thermal_setField(T,dot_T, co,ce) real(pReal), intent(in) :: T, dot_T - integer, intent(in) :: ce, co + integer, intent(in) :: co, ce end subroutine phase_thermal_setField module subroutine phase_set_phi(phi,co,ce) @@ -192,6 +192,28 @@ module phase integer, intent(in) :: co, ce end subroutine phase_set_phi + + module function phase_mu_phi(co,ce) result(mu) + integer, intent(in) :: co, ce + real(pReal) :: mu + end function phase_mu_phi + + module function phase_K_phi(co,ce) result(K) + integer, intent(in) :: co, ce + real(pReal), dimension(3,3) :: K + end function phase_K_phi + + + module function phase_mu_T(co,ce) result(mu) + integer, intent(in) :: co, ce + real(pReal) :: mu + end function phase_mu_T + + module function phase_K_T(co,ce) result(K) + integer, intent(in) :: co, ce + real(pReal), dimension(3,3) :: K + end function phase_K_T + ! == cleaned:end =================================================================================== module function thermal_stress(Delta_t,ph,me) result(converged_) @@ -297,6 +319,10 @@ module phase phase_homogenizedC, & phase_f_phi, & phase_f_T, & + phase_K_phi, & + phase_K_T, & + phase_mu_phi, & + phase_mu_T, & phase_results, & phase_allocateState, & phase_forward, & diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index 5f6d65ab8..9a20030d2 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -345,6 +345,33 @@ function phase_damage_collectDotState(ph,me) result(broken) end function phase_damage_collectDotState +!-------------------------------------------------------------------------------------------------- +!> @brief Damage viscosity. +!-------------------------------------------------------------------------------------------------- +module function phase_mu_phi(co,ce) result(mu) + + integer, intent(in) :: co, ce + real(pReal) :: mu + + + mu = lattice_mu_phi(material_phaseID(co,ce)) + +end function phase_mu_phi + + +!-------------------------------------------------------------------------------------------------- +!> @brief Damage conductivity/diffusivity in reference configuration. +!-------------------------------------------------------------------------------------------------- +module function phase_K_phi(co,ce) result(K) + + integer, intent(in) :: co, ce + real(pReal), dimension(3,3) :: K + + + K = crystallite_push33ToRef(co,ce,lattice_K_phi(1:3,1:3,material_phaseID(co,ce))) + +end function phase_K_phi + !-------------------------------------------------------------------------------------------------- !> @brief for constitutive models having an instantaneous change of state diff --git a/src/phase_thermal.f90 b/src/phase_thermal.f90 index c2b4b34b2..a0e6adb60 100644 --- a/src/phase_thermal.f90 +++ b/src/phase_thermal.f90 @@ -184,6 +184,35 @@ function phase_thermal_collectDotState(ph,me) result(broken) end function phase_thermal_collectDotState +!-------------------------------------------------------------------------------------------------- +!> @brief Damage viscosity. +!-------------------------------------------------------------------------------------------------- +module function phase_mu_T(co,ce) result(mu) + + integer, intent(in) :: co, ce + real(pReal) :: mu + + + mu = lattice_c_p(material_phaseID(co,ce)) & + * lattice_rho(material_phaseID(co,ce)) + +end function phase_mu_T + + +!-------------------------------------------------------------------------------------------------- +!> @brief Damage conductivity/diffusivity in reference configuration. +!-------------------------------------------------------------------------------------------------- +module function phase_K_T(co,ce) result(K) + + integer, intent(in) :: co, ce + real(pReal), dimension(3,3) :: K + + + K = crystallite_push33ToRef(co,ce,lattice_K_T(1:3,1:3,material_phaseID(co,ce))) + +end function phase_K_T + + module function thermal_stress(Delta_t,ph,me) result(converged_) ! ?? why is this called "stress" when it seems closer to "updateState" ?? real(pReal), intent(in) :: Delta_t From f655a6fe5cadd6f012726339786b698e6981deb1 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 13:55:30 +0200 Subject: [PATCH 176/219] store data locally --- src/lattice.f90 | 43 ++++++------------------------------------- src/phase_damage.f90 | 12 +++++++----- src/phase_thermal.f90 | 13 +++++++++---- 3 files changed, 22 insertions(+), 46 deletions(-) diff --git a/src/lattice.f90 b/src/lattice.f90 index 69ee65857..06986b42b 100644 --- a/src/lattice.f90 +++ b/src/lattice.f90 @@ -398,9 +398,7 @@ module lattice lattice_rho, & lattice_c_p real(pReal), dimension(:,:,:), allocatable, public, protected :: & - lattice_C66, & - lattice_K_T, & - lattice_K_phi + lattice_C66 integer(kind(lattice_UNDEFINED_ID)), dimension(:), allocatable, public, protected :: & lattice_structure ! SHOULD NOT BE PART OF LATTICE END @@ -458,23 +456,19 @@ subroutine lattice_init phases, & phase, & mech, & - elasticity, & - thermal, & - damage + elasticity print'(/,a)', ' <<<+- lattice init -+>>>'; flush(IO_STDOUT) +! SHOULD NOT BE PART OF LATTICE BEGIN + phases => config_material%get('phase') Nphases = phases%length allocate(lattice_structure(Nphases),source = lattice_UNDEFINED_ID) allocate(lattice_C66(6,6,Nphases), source=0.0_pReal) - allocate(lattice_K_T (3,3,Nphases), source=0.0_pReal) - allocate(lattice_K_phi (3,3,Nphases), source=0.0_pReal) - - allocate(lattice_mu_phi,& - lattice_rho,lattice_c_p, & + allocate(lattice_rho, & lattice_mu, lattice_nu,& source=[(0.0_pReal,i=1,Nphases)]) @@ -522,32 +516,7 @@ subroutine lattice_init enddo lattice_rho(ph) = phase%get_asFloat('rho', defaultVal=0.0_pReal) - - ! SHOULD NOT BE PART OF LATTICE BEGIN - - if (phase%contains('thermal')) then - thermal => phase%get('thermal') - lattice_K_T(1,1,ph) = thermal%get_asFloat('K_11',defaultVal=0.0_pReal) - lattice_K_T(2,2,ph) = thermal%get_asFloat('K_22',defaultVal=0.0_pReal) - lattice_K_T(3,3,ph) = thermal%get_asFloat('K_33',defaultVal=0.0_pReal) - lattice_K_T(1:3,1:3,ph) = lattice_applyLatticeSymmetry33(lattice_K_T(1:3,1:3,ph), & - phase%get_asString('lattice')) - lattice_c_p(ph) = thermal%get_asFloat('c_p', defaultVal=0.0_pReal) - endif - - - if (phase%contains('damage')) then - damage => phase%get('damage') - damage => damage%get(1) - lattice_K_phi(1,1,ph) = damage%get_asFloat('D_11',defaultVal=0.0_pReal) - lattice_K_phi(2,2,ph) = damage%get_asFloat('D_22',defaultVal=0.0_pReal) - lattice_K_phi(3,3,ph) = damage%get_asFloat('D_33',defaultVal=0.0_pReal) - lattice_K_phi(1:3,1:3,ph) = lattice_applyLatticeSymmetry33(lattice_K_phi(1:3,1:3,ph), & - phase%get_asString('lattice')) - - lattice_mu_phi(ph) = damage%get_asFloat('M',defaultVal=0.0_pReal) - endif - ! SHOULD NOT BE PART OF LATTICE END +! SHOULD NOT BE PART OF LATTICE END call selfTest diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index 9a20030d2..8df2cd5e4 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -131,9 +131,11 @@ module subroutine damage_init if (sources%length == 1) then damage_active = .true. source => sources%get(1) - param(ph)%K(1,1) = source%get_asFloat('K_11',defaultVal=0.0_pReal) - param(ph)%K(2,2) = source%get_asFloat('K_22',defaultVal=0.0_pReal) - param(ph)%K(3,3) = source%get_asFloat('K_33',defaultVal=0.0_pReal) + param(ph)%mu = source%get_asFloat('M',defaultVal=0.0_pReal) + param(ph)%K(1,1) = source%get_asFloat('D_11',defaultVal=0.0_pReal) + param(ph)%K(2,2) = source%get_asFloat('D_22',defaultVal=0.0_pReal) + param(ph)%K(3,3) = source%get_asFloat('D_33',defaultVal=0.0_pReal) + param(ph)%K = lattice_applyLatticeSymmetry33(param(ph)%K,phase%get_asString('lattice')) endif enddo @@ -354,7 +356,7 @@ module function phase_mu_phi(co,ce) result(mu) real(pReal) :: mu - mu = lattice_mu_phi(material_phaseID(co,ce)) + mu = param(material_phaseID(co,ce))%mu end function phase_mu_phi @@ -368,7 +370,7 @@ module function phase_K_phi(co,ce) result(K) real(pReal), dimension(3,3) :: K - K = crystallite_push33ToRef(co,ce,lattice_K_phi(1:3,1:3,material_phaseID(co,ce))) + K = crystallite_push33ToRef(co,ce,param(material_phaseID(co,ce))%K) end function phase_K_phi diff --git a/src/phase_thermal.f90 b/src/phase_thermal.f90 index a0e6adb60..f6d046266 100644 --- a/src/phase_thermal.f90 +++ b/src/phase_thermal.f90 @@ -100,12 +100,17 @@ module subroutine thermal_init(phases) allocate(current(ph)%dot_T(Nmembers),source=0.0_pReal) phase => phases%get(ph) thermal => phase%get('thermal',defaultVal=emptyDict) - sources => thermal%get('source',defaultVal=emptyList) + param(ph)%C_p = thermal%get_asFloat('c_p',defaultVal=0.0_pReal) + if (param(ph)%C_p <= 0) param(ph)%C_p = thermal%get_asFloat('C_p',defaultVal=0.0_pReal) param(ph)%K(1,1) = thermal%get_asFloat('K_11',defaultVal=0.0_pReal) param(ph)%K(2,2) = thermal%get_asFloat('K_22',defaultVal=0.0_pReal) param(ph)%K(3,3) = thermal%get_asFloat('K_33',defaultVal=0.0_pReal) + param(ph)%K = lattice_applyLatticeSymmetry33(param(ph)%K,phase%get_asString('lattice')) + + sources => thermal%get('source',defaultVal=emptyList) thermal_Nsources(ph) = sources%length allocate(thermalstate(ph)%p(thermal_Nsources(ph))) + enddo allocate(thermal_source(maxval(thermal_Nsources),phases%length), source = THERMAL_UNDEFINED_ID) @@ -193,8 +198,8 @@ module function phase_mu_T(co,ce) result(mu) real(pReal) :: mu - mu = lattice_c_p(material_phaseID(co,ce)) & - * lattice_rho(material_phaseID(co,ce)) + mu = lattice_rho(material_phaseID(co,ce)) & + * param(material_phaseID(co,ce))%C_p end function phase_mu_T @@ -208,7 +213,7 @@ module function phase_K_T(co,ce) result(K) real(pReal), dimension(3,3) :: K - K = crystallite_push33ToRef(co,ce,lattice_K_T(1:3,1:3,material_phaseID(co,ce))) + K = crystallite_push33ToRef(co,ce,param(material_phaseID(co,ce))%K) end function phase_K_T From 887524bcc1cd53bc6a842f0da5799d9082656ede Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 11 Apr 2021 15:32:17 +0200 Subject: [PATCH 177/219] polishing --- src/grid/grid_damage_spectral.f90 | 27 ++++++++++---------- src/grid/grid_thermal_spectral.f90 | 34 +++++++++++-------------- src/homogenization_damage.f90 | 39 +++++++++++------------------ src/homogenization_damage_pass.f90 | 5 ++-- src/homogenization_thermal.f90 | 4 +-- src/homogenization_thermal_pass.f90 | 5 ++-- 6 files changed, 52 insertions(+), 62 deletions(-) diff --git a/src/grid/grid_damage_spectral.f90 b/src/grid/grid_damage_spectral.f90 index 7fe9a4a25..967ddb73a 100644 --- a/src/grid/grid_damage_spectral.f90 +++ b/src/grid/grid_damage_spectral.f90 @@ -15,8 +15,8 @@ module grid_damage_spectral use IO use spectral_utilities use discretization_grid - use YAML_types use homogenization + use YAML_types use config implicit none @@ -61,7 +61,7 @@ contains !> @brief allocates all neccessary fields and fills them with data ! ToDo: Restart not implemented !-------------------------------------------------------------------------------------------------- -subroutine grid_damage_spectral_init +subroutine grid_damage_spectral_init() PetscInt, dimension(0:worldsize-1) :: localK DM :: damage_grid @@ -88,10 +88,10 @@ subroutine grid_damage_spectral_init num_generic => config_numerics%get('generic',defaultVal=emptyDict) num%residualStiffness = num_generic%get_asFloat('residualStiffness', defaultVal=1.0e-6_pReal) - if (num%residualStiffness < 0.0_pReal) call IO_error(301,ext_msg='residualStiffness') - if (num%itmax <= 1) call IO_error(301,ext_msg='itmax') - if (num%eps_damage_atol <= 0.0_pReal) call IO_error(301,ext_msg='eps_damage_atol') - if (num%eps_damage_rtol <= 0.0_pReal) call IO_error(301,ext_msg='eps_damage_rtol') + if (num%residualStiffness < 0.0_pReal) call IO_error(301,ext_msg='residualStiffness') + if (num%itmax <= 1) call IO_error(301,ext_msg='itmax') + if (num%eps_damage_atol <= 0.0_pReal) call IO_error(301,ext_msg='eps_damage_atol') + if (num%eps_damage_rtol <= 0.0_pReal) call IO_error(301,ext_msg='eps_damage_rtol') !-------------------------------------------------------------------------------------------------- ! set default and user defined options for PETSc @@ -146,6 +146,7 @@ subroutine grid_damage_spectral_init allocate(phi_current(grid(1),grid(2),grid3), source=1.0_pReal) allocate(phi_lastInc(grid(1),grid(2),grid3), source=1.0_pReal) allocate(phi_stagInc(grid(1),grid(2),grid3), source=1.0_pReal) + call VecSet(solution_vec,1.0_pReal,ierr); CHKERRQ(ierr) call updateReference @@ -216,21 +217,21 @@ end function grid_damage_spectral_solution subroutine grid_damage_spectral_forward(cutBack) logical, intent(in) :: cutBack - integer :: i, j, k, ce + integer :: i, j, k, ce DM :: dm_local - PetscScalar, dimension(:,:,:), pointer :: x_scal - PetscErrorCode :: ierr + PetscScalar, dimension(:,:,:), pointer :: x_scal + PetscErrorCode :: ierr if (cutBack) then phi_current = phi_lastInc phi_stagInc = phi_lastInc !-------------------------------------------------------------------------------------------------- ! reverting damage field state - ce = 0 call SNESGetDM(damage_snes,dm_local,ierr); CHKERRQ(ierr) call DMDAVecGetArrayF90(dm_local,solution_vec,x_scal,ierr); CHKERRQ(ierr) !< get the data out of PETSc to work with x_scal(xstart:xend,ystart:yend,zstart:zend) = phi_current call DMDAVecRestoreArrayF90(dm_local,solution_vec,x_scal,ierr); CHKERRQ(ierr) + ce = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 call homogenization_set_phi(phi_current(i,j,k),ce) @@ -271,8 +272,7 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) ce = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - vectorField_real(1:3,i,j,k) = matmul(homogenization_K_phi(ce) - K_ref, & - vectorField_real(1:3,i,j,k)) + vectorField_real(1:3,i,j,k) = matmul(homogenization_K_phi(ce) - K_ref, vectorField_real(1:3,i,j,k)) enddo; enddo; enddo call utilities_FFTvectorForward call utilities_fourierVectorDivergence !< calculate damage divergence in fourier field @@ -290,6 +290,7 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) call utilities_FFTscalarForward call utilities_fourierGreenConvolution(K_ref, mu_ref, params%timeinc) call utilities_FFTscalarBackward + where(scalarField_real(1:grid(1),1:grid(2),1:grid3) > phi_lastInc) & scalarField_real(1:grid(1),1:grid(2),1:grid3) = phi_lastInc where(scalarField_real(1:grid(1),1:grid(2),1:grid3) < num%residualStiffness) & @@ -305,7 +306,7 @@ end subroutine formResidual !-------------------------------------------------------------------------------------------------- !> @brief update reference viscosity and conductivity !-------------------------------------------------------------------------------------------------- -subroutine updateReference +subroutine updateReference() integer :: ce,ierr diff --git a/src/grid/grid_thermal_spectral.f90 b/src/grid/grid_thermal_spectral.f90 index 60d8d99db..1ccb3b901 100644 --- a/src/grid/grid_thermal_spectral.f90 +++ b/src/grid/grid_thermal_spectral.f90 @@ -18,7 +18,6 @@ module grid_thermal_spectral use homogenization use YAML_types use config - use material implicit none private @@ -46,7 +45,7 @@ module grid_thermal_spectral !-------------------------------------------------------------------------------------------------- ! reference diffusion tensor, mobility etc. - integer :: totalIter = 0 !< total iteration in current increment + integer :: totalIter = 0 !< total iteration in current increment real(pReal), dimension(3,3) :: K_ref real(pReal) :: mu_ref @@ -68,7 +67,7 @@ subroutine grid_thermal_spectral_init(T_0) PetscInt, dimension(0:worldsize-1) :: localK integer :: i, j, k, ce DM :: thermal_grid - PetscScalar, dimension(:,:,:), pointer :: x_scal + PetscScalar, dimension(:,:,:), pointer :: T_PETSc PetscErrorCode :: ierr class(tNode), pointer :: & num_grid @@ -85,9 +84,9 @@ subroutine grid_thermal_spectral_init(T_0) num%eps_thermal_atol = num_grid%get_asFloat ('eps_thermal_atol',defaultVal=1.0e-2_pReal) num%eps_thermal_rtol = num_grid%get_asFloat ('eps_thermal_rtol',defaultVal=1.0e-6_pReal) - if (num%itmax <= 1) call IO_error(301,ext_msg='itmax') - if (num%eps_thermal_atol <= 0.0_pReal) call IO_error(301,ext_msg='eps_thermal_atol') - if (num%eps_thermal_rtol <= 0.0_pReal) call IO_error(301,ext_msg='eps_thermal_rtol') + if (num%itmax <= 1) call IO_error(301,ext_msg='itmax') + if (num%eps_thermal_atol <= 0.0_pReal) call IO_error(301,ext_msg='eps_thermal_atol') + if (num%eps_thermal_rtol <= 0.0_pReal) call IO_error(301,ext_msg='eps_thermal_rtol') !-------------------------------------------------------------------------------------------------- ! set default and user defined options for PETSc @@ -130,6 +129,7 @@ subroutine grid_thermal_spectral_init(T_0) allocate(T_current(grid(1),grid(2),grid3), source=0.0_pReal) allocate(T_lastInc(grid(1),grid(2),grid3), source=0.0_pReal) allocate(T_stagInc(grid(1),grid(2),grid3), source=0.0_pReal) + ce = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 @@ -138,9 +138,10 @@ subroutine grid_thermal_spectral_init(T_0) T_stagInc(i,j,k) = T_current(i,j,k) call homogenization_thermal_setField(T_0,0.0_pReal,ce) enddo; enddo; enddo - call DMDAVecGetArrayF90(thermal_grid,solution_vec,x_scal,ierr); CHKERRQ(ierr) !< get the data out of PETSc to work with - x_scal(xstart:xend,ystart:yend,zstart:zend) = T_current - call DMDAVecRestoreArrayF90(thermal_grid,solution_vec,x_scal,ierr); CHKERRQ(ierr) + + call DMDAVecGetArrayF90(thermal_grid,solution_vec,T_PETSc,ierr); CHKERRQ(ierr) + T_PETSc(xstart:xend,ystart:yend,zstart:zend) = T_current + call DMDAVecRestoreArrayF90(thermal_grid,solution_vec,T_PETSc,ierr); CHKERRQ(ierr) call updateReference @@ -190,9 +191,7 @@ function grid_thermal_spectral_solution(timeinc) result(solution) ce = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - call homogenization_thermal_setField(T_current(i,j,k), & - (T_current(i,j,k)-T_lastInc(i,j,k))/params%timeinc, & - ce) + call homogenization_thermal_setField(T_current(i,j,k),(T_current(i,j,k)-T_lastInc(i,j,k))/params%timeinc,ce) enddo; enddo; enddo call VecMin(solution_vec,devNull,T_min,ierr); CHKERRQ(ierr) @@ -223,16 +222,14 @@ subroutine grid_thermal_spectral_forward(cutBack) !-------------------------------------------------------------------------------------------------- ! reverting thermal field state - ce = 0 call SNESGetDM(thermal_snes,dm_local,ierr); CHKERRQ(ierr) call DMDAVecGetArrayF90(dm_local,solution_vec,x_scal,ierr); CHKERRQ(ierr) !< get the data out of PETSc to work with x_scal(xstart:xend,ystart:yend,zstart:zend) = T_current call DMDAVecRestoreArrayF90(dm_local,solution_vec,x_scal,ierr); CHKERRQ(ierr) + ce = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - call homogenization_thermal_setField(T_current(i,j,k), & - (T_current(i,j,k)-T_lastInc(i,j,k))/params%timeinc, & - ce) + call homogenization_thermal_setField(T_current(i,j,k),(T_current(i,j,k)-T_lastInc(i,j,k))/params%timeinc,ce) enddo; enddo; enddo else T_lastInc = T_current @@ -270,8 +267,7 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr) ce = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) ce = ce + 1 - vectorField_real(1:3,i,j,k) = matmul(homogenization_K_T(ce) - K_ref, & - vectorField_real(1:3,i,j,k)) + vectorField_real(1:3,i,j,k) = matmul(homogenization_K_T(ce) - K_ref, vectorField_real(1:3,i,j,k)) enddo; enddo; enddo call utilities_FFTvectorForward call utilities_fourierVectorDivergence !< calculate temperature divergence in fourier field @@ -300,7 +296,7 @@ end subroutine formResidual !-------------------------------------------------------------------------------------------------- !> @brief update reference viscosity and conductivity !-------------------------------------------------------------------------------------------------- -subroutine updateReference +subroutine updateReference() integer :: ce,ierr diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index b8aecccae..0546834fd 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -38,14 +38,12 @@ module subroutine damage_init() configHomogenizations, & configHomogenization, & configHomogenizationDamage, & - num_generic, & - material_homogenization - integer :: ho - integer :: Ninstances,Nmaterialpoints,h + num_generic + integer :: ho,Nmaterialpoints print'(/,a)', ' <<<+- homogenization:damage init -+>>>' - print'(/,a)', ' <<<+- homogenization:damage:pass init -+>>>' + configHomogenizations => config_material%get('homogenization') allocate(param(configHomogenizations%length)) @@ -62,6 +60,10 @@ module subroutine damage_init() #else prm%output = configHomogenizationDamage%get_as1dString('output',defaultVal=emptyStringArray) #endif + Nmaterialpoints = count(material_homogenizationAt == ho) + damageState_h(ho)%sizeState = 1 + allocate(damageState_h(ho)%state0(1,Nmaterialpoints), source=1.0_pReal) + allocate(damageState_h(ho)%state (1,Nmaterialpoints), source=1.0_pReal) else prm%output = emptyStringArray endif @@ -73,18 +75,7 @@ module subroutine damage_init() num_generic => config_numerics%get('generic',defaultVal= emptyDict) num_damage%charLength = num_generic%get_asFloat('charLength',defaultVal=1.0_pReal) - Ninstances = count(damage_type == DAMAGE_nonlocal_ID) - - material_homogenization => config_material%get('homogenization') - do h = 1, material_homogenization%length - if (damage_type(h) /= DAMAGE_NONLOCAL_ID) cycle - - Nmaterialpoints = count(material_homogenizationAt == h) - damageState_h(h)%sizeState = 1 - allocate(damageState_h(h)%state0 (1,Nmaterialpoints), source=1.0_pReal) - allocate(damageState_h(h)%state (1,Nmaterialpoints), source=1.0_pReal) - - enddo + call pass_init() end subroutine damage_init @@ -183,13 +174,13 @@ module subroutine damage_results(ho,group) integer :: o associate(prm => param(ho)) - outputsLoop: do o = 1,size(prm%output) - select case(prm%output(o)) - case ('phi') - call results_writeDataset(group,damagestate_h(ho)%state(1,:),prm%output(o),& - 'damage indicator','-') - end select - enddo outputsLoop + outputsLoop: do o = 1,size(prm%output) + select case(prm%output(o)) + case ('phi') + call results_writeDataset(group,damagestate_h(ho)%state(1,:),prm%output(o),& + 'damage indicator','-') + end select + enddo outputsLoop end associate end subroutine damage_results diff --git a/src/homogenization_damage_pass.f90 b/src/homogenization_damage_pass.f90 index cbb7ec79f..bdb44b822 100644 --- a/src/homogenization_damage_pass.f90 +++ b/src/homogenization_damage_pass.f90 @@ -6,8 +6,9 @@ submodule(homogenization:damage) damage_pass contains -module subroutine pass_init - +module subroutine pass_init() + + print'(/,a)', ' <<<+- homogenization:damage:pass init -+>>>' end subroutine pass_init diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index 0effe09ed..f681036de 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -45,8 +45,6 @@ module subroutine thermal_init() print'(/,a)', ' <<<+- homogenization:thermal init -+>>>' - print'(/,a)', ' <<<+- homogenization:thermal:pass init -+>>>' - configHomogenizations => config_material%get('homogenization') @@ -71,6 +69,8 @@ module subroutine thermal_init() end associate enddo + call pass_init() + end subroutine thermal_init diff --git a/src/homogenization_thermal_pass.f90 b/src/homogenization_thermal_pass.f90 index 940a15024..87020d8d2 100644 --- a/src/homogenization_thermal_pass.f90 +++ b/src/homogenization_thermal_pass.f90 @@ -6,8 +6,9 @@ submodule(homogenization:thermal) thermal_pass contains -module subroutine pass_init - +module subroutine pass_init() + + print'(/,a)', ' <<<+- homogenization:thermal:pass init -+>>>' end subroutine pass_init From 90e33b14bfe95cbc6b997c0f838b89f65228a5b9 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 12 Apr 2021 11:27:44 +0200 Subject: [PATCH 178/219] [skip ci] updated version information after successful test of v3.0.0-alpha2-839-gc55724d95 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6855a7dca..f8cfbf476 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-829-g73b07eda4 +v3.0.0-alpha2-839-gc55724d95 From 74548d5f51a3cb9c622355c26cfc8bf1c2c6d0ee Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 12 Apr 2021 21:21:15 +0200 Subject: [PATCH 179/219] new names (as in HDF5 out) --- src/phase.f90 | 16 +- src/phase_mechanical.f90 | 322 ++++++++++----------- src/phase_mechanical_eigen.f90 | 12 +- src/phase_mechanical_plastic.f90 | 60 ++-- src/phase_mechanical_plastic_dislotwin.f90 | 12 +- src/phase_mechanical_plastic_isotropic.f90 | 6 +- 6 files changed, 213 insertions(+), 215 deletions(-) diff --git a/src/phase.f90 b/src/phase.f90 index 54116f3c9..b65bf334f 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -135,18 +135,18 @@ module phase end subroutine mechanical_restartRead - module function mechanical_S(ph,me) result(S) - integer, intent(in) :: ph,me + module function mechanical_S(ph,en) result(S) + integer, intent(in) :: ph,en real(pReal), dimension(3,3) :: S end function mechanical_S - module function mechanical_L_p(ph,me) result(L_p) - integer, intent(in) :: ph,me + module function mechanical_L_p(ph,en) result(L_p) + integer, intent(in) :: ph,en real(pReal), dimension(3,3) :: L_p end function mechanical_L_p - module function mechanical_F_e(ph,me) result(F_e) - integer, intent(in) :: ph,me + module function mechanical_F_e(ph,en) result(F_e) + integer, intent(in) :: ph,en real(pReal), dimension(3,3) :: F_e end function mechanical_F_e @@ -239,8 +239,8 @@ module phase logical :: converged_ end function crystallite_stress - module function phase_homogenizedC(ph,me) result(C) - integer, intent(in) :: ph, me + module function phase_homogenizedC(ph,en) result(C) + integer, intent(in) :: ph, en real(pReal), dimension(6,6) :: C end function phase_homogenizedC diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index 9f2bc4df2..6bcfc9a75 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -60,7 +60,7 @@ submodule(phase) mechanical module subroutine plastic_init end subroutine plastic_init - module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,ph,me) + module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,ph,en) real(pReal), dimension(3,3), intent(out) :: & Li !< inleastic velocity gradient real(pReal), dimension(3,3,3,3), intent(out) :: & @@ -69,34 +69,34 @@ submodule(phase) mechanical Mi !< Mandel stress integer, intent(in) :: & ph, & - me + en end subroutine plastic_isotropic_LiAndItsTangent - module function plastic_dotState(subdt,co,ip,el,ph,me) result(broken) + module function plastic_dotState(subdt,co,ip,el,ph,en) result(broken) integer, intent(in) :: & co, & !< component-ID of integration point ip, & !< integration point el, & !< element ph, & - me + en real(pReal), intent(in) :: & subdt !< timestep logical :: broken end function plastic_dotState - module function plastic_deltaState(ph, me) result(broken) + module function plastic_deltaState(ph, en) result(broken) integer, intent(in) :: & ph, & - me + en logical :: & broken end function plastic_deltaState module subroutine phase_LiAndItsTangents(Li, dLi_dS, dLi_dFi, & - S, Fi, ph,me) + S, Fi, ph,en) integer, intent(in) :: & - ph,me + ph,en real(pReal), intent(in), dimension(3,3) :: & S !< 2nd Piola-Kirchhoff stress real(pReal), intent(in), dimension(3,3) :: & @@ -111,9 +111,9 @@ submodule(phase) mechanical module subroutine plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & - S, Fi, ph,me) + S, Fi, ph,en) integer, intent(in) :: & - ph,me + ph,en real(pReal), intent(in), dimension(3,3) :: & S, & !< 2nd Piola-Kirchhoff stress Fi !< intermediate deformation gradient @@ -155,9 +155,9 @@ submodule(phase) mechanical character(len=*), intent(in) :: group end subroutine plastic_nonlocal_results - module function plastic_dislotwin_homogenizedC(ph,me) result(homogenizedC) + module function plastic_dislotwin_homogenizedC(ph,en) result(homogenizedC) real(pReal), dimension(6,6) :: homogenizedC - integer, intent(in) :: ph,me + integer, intent(in) :: ph,en end function plastic_dislotwin_homogenizedC @@ -189,7 +189,7 @@ module subroutine mechanical_init(materials,phases) co, & ce, & ph, & - me, & + en, & stiffDegradationCtr, & Nmembers class(tNode), pointer :: & @@ -286,21 +286,21 @@ module subroutine mechanical_init(materials,phases) constituent => constituents%get(co) ph = material_phaseAt(co,el) - me = material_phaseMemberAt(co,ip,el) + en = material_phaseMemberAt(co,ip,el) - call material_orientation0(co,ph,me)%fromQuaternion(constituent%get_as1dFloat('O',requiredSize=4)) + call material_orientation0(co,ph,en)%fromQuaternion(constituent%get_as1dFloat('O',requiredSize=4)) - phase_mechanical_Fp0(ph)%data(1:3,1:3,me) = material_orientation0(co,ph,me)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) - phase_mechanical_Fp0(ph)%data(1:3,1:3,me) = phase_mechanical_Fp0(ph)%data(1:3,1:3,me) & - / math_det33(phase_mechanical_Fp0(ph)%data(1:3,1:3,me))**(1.0_pReal/3.0_pReal) - phase_mechanical_Fi0(ph)%data(1:3,1:3,me) = math_I3 - phase_mechanical_F0(ph)%data(1:3,1:3,me) = math_I3 + phase_mechanical_Fp0(ph)%data(1:3,1:3,en) = material_orientation0(co,ph,en)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) + phase_mechanical_Fp0(ph)%data(1:3,1:3,en) = phase_mechanical_Fp0(ph)%data(1:3,1:3,en) & + / math_det33(phase_mechanical_Fp0(ph)%data(1:3,1:3,en))**(1.0_pReal/3.0_pReal) + phase_mechanical_Fi0(ph)%data(1:3,1:3,en) = math_I3 + phase_mechanical_F0(ph)%data(1:3,1:3,en) = math_I3 - phase_mechanical_Fe(ph)%data(1:3,1:3,me) = math_inv33(matmul(phase_mechanical_Fi0(ph)%data(1:3,1:3,me), & - phase_mechanical_Fp0(ph)%data(1:3,1:3,me))) ! assuming that euler angles are given in internal strain free configuration - phase_mechanical_Fp(ph)%data(1:3,1:3,me) = phase_mechanical_Fp0(ph)%data(1:3,1:3,me) - phase_mechanical_Fi(ph)%data(1:3,1:3,me) = phase_mechanical_Fi0(ph)%data(1:3,1:3,me) - phase_mechanical_F(ph)%data(1:3,1:3,me) = phase_mechanical_F0(ph)%data(1:3,1:3,me) + phase_mechanical_Fe(ph)%data(1:3,1:3,en) = math_inv33(matmul(phase_mechanical_Fi0(ph)%data(1:3,1:3,en), & + phase_mechanical_Fp0(ph)%data(1:3,1:3,en))) ! assuming that euler angles are given in internal strain free configuration + phase_mechanical_Fp(ph)%data(1:3,1:3,en) = phase_mechanical_Fp0(ph)%data(1:3,1:3,en) + phase_mechanical_Fi(ph)%data(1:3,1:3,en) = phase_mechanical_Fi0(ph)%data(1:3,1:3,en) + phase_mechanical_F(ph)%data(1:3,1:3,en) = phase_mechanical_F0(ph)%data(1:3,1:3,en) enddo enddo; enddo @@ -353,11 +353,11 @@ end subroutine mechanical_init !> the elastic and intermediate deformation gradients using Hooke's law !-------------------------------------------------------------------------------------------------- subroutine phase_hooke_SandItsTangents(S, dS_dFe, dS_dFi, & - Fe, Fi, ph, me) + Fe, Fi, ph, en) integer, intent(in) :: & ph, & - me + en real(pReal), intent(in), dimension(3,3) :: & Fe, & !< elastic deformation gradient Fi !< intermediate deformation gradient @@ -373,12 +373,12 @@ subroutine phase_hooke_SandItsTangents(S, dS_dFe, dS_dFi, & d, & !< counter in degradation loop i, j - C = math_66toSym3333(phase_homogenizedC(ph,me)) + C = math_66toSym3333(phase_homogenizedC(ph,en)) DegradationLoop: do d = 1, phase_NstiffnessDegradations(ph) degradationType: select case(phase_stiffnessDegradation(d,ph)) case (STIFFNESS_DEGRADATION_damage_ID) degradationType - C = C * damage_phi(ph,me)**2 + C = C * damage_phi(ph,en)**2 end select degradationType enddo DegradationLoop @@ -486,7 +486,7 @@ function integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) result(broken) o, & p, & ph, & - me, & + en, & jacoCounterLp, & jacoCounterLi ! counters to check for Jacobian update logical :: error,broken @@ -495,12 +495,12 @@ function integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) result(broken) broken = .true. ph = material_phaseAt(co,el) - me = material_phaseMemberAt(co,ip,el) + en = material_phaseMemberAt(co,ip,el) call plastic_dependentState(co,ip,el) - Lpguess = phase_mechanical_Lp(ph)%data(1:3,1:3,me) ! take as first guess - Liguess = phase_mechanical_Li(ph)%data(1:3,1:3,me) ! take as first guess + Lpguess = phase_mechanical_Lp(ph)%data(1:3,1:3,en) ! take as first guess + Liguess = phase_mechanical_Li(ph)%data(1:3,1:3,en) ! take as first guess call math_invert33(invFp_current,devNull,error,subFp0) if (error) return ! error @@ -535,10 +535,10 @@ function integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) result(broken) B = math_I3 - Delta_t*Lpguess Fe = matmul(matmul(A,B), invFi_new) call phase_hooke_SandItsTangents(S, dS_dFe, dS_dFi, & - Fe, Fi_new, ph, me) + Fe, Fi_new, ph, en) call plastic_LpAndItsTangents(Lp_constitutive, dLp_dS, dLp_dFi, & - S, Fi_new, ph,me) + S, Fi_new, ph,en) !* update current residuum and check for convergence of loop atol_Lp = max(num%rtol_crystalliteStress * max(norm2(Lpguess),norm2(Lp_constitutive)), & ! absolute tolerance from largest acceptable relative error @@ -579,7 +579,7 @@ function integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) result(broken) enddo LpLoop call phase_LiAndItsTangents(Li_constitutive, dLi_dS, dLi_dFi, & - S, Fi_new, ph,me) + S, Fi_new, ph,en) !* update current residuum and check for convergence of loop atol_Li = max(num%rtol_crystalliteStress * max(norm2(Liguess),norm2(Li_constitutive)), & ! absolute tolerance from largest acceptable relative error @@ -629,13 +629,13 @@ function integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) result(broken) call math_invert33(Fp_new,devNull,error,invFp_new) if (error) return ! error - phase_mechanical_P(ph)%data(1:3,1:3,me) = matmul(matmul(F,invFp_new),matmul(S,transpose(invFp_new))) - phase_mechanical_S(ph)%data(1:3,1:3,me) = S - phase_mechanical_Lp(ph)%data(1:3,1:3,me) = Lpguess - phase_mechanical_Li(ph)%data(1:3,1:3,me) = Liguess - phase_mechanical_Fp(ph)%data(1:3,1:3,me) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize - phase_mechanical_Fi(ph)%data(1:3,1:3,me) = Fi_new - phase_mechanical_Fe(ph)%data(1:3,1:3,me) = matmul(matmul(F,invFp_new),invFi_new) + phase_mechanical_P(ph)%data(1:3,1:3,en) = matmul(matmul(F,invFp_new),matmul(S,transpose(invFp_new))) + phase_mechanical_S(ph)%data(1:3,1:3,en) = S + phase_mechanical_Lp(ph)%data(1:3,1:3,en) = Lpguess + phase_mechanical_Li(ph)%data(1:3,1:3,en) = Liguess + phase_mechanical_Fp(ph)%data(1:3,1:3,en) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize + phase_mechanical_Fi(ph)%data(1:3,1:3,en) = Fi_new + phase_mechanical_Fe(ph)%data(1:3,1:3,en) = matmul(matmul(F,invFp_new),invFi_new) broken = .false. end function integrateStress @@ -660,7 +660,7 @@ function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) resul integer :: & NiterationState, & !< number of iterations in state loop ph, & - me, & + en, & sizeDotState real(pReal) :: & zeta @@ -671,38 +671,37 @@ function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) resul ph = material_phaseAt(co,el) - me = material_phaseMemberAt(co,ip,el) + en = material_phaseMemberAt(co,ip,el) - broken = plastic_dotState(Delta_t, co,ip,el,ph,me) + broken = plastic_dotState(Delta_t, co,ip,el,ph,en) if(broken) return sizeDotState = plasticState(ph)%sizeDotState - plasticState(ph)%state(1:sizeDotState,me) = subState0 & - + plasticState(ph)%dotState (1:sizeDotState,me) * Delta_t - dotState(1:sizeDotState,2) = 0.0_pReal + plasticState(ph)%state(1:sizeDotState,en) = subState0 & + + plasticState(ph)%dotState (1:sizeDotState,en) * Delta_t iteration: do NiterationState = 1, num%nState - if(nIterationState > 1) dotState(1:sizeDotState,2) = dotState(1:sizeDotState,1) - dotState(1:sizeDotState,1) = plasticState(ph)%dotState(:,me) + dotState(1:sizeDotState,2) = merge(dotState(1:sizeDotState,1),0.0, nIterationState > 1) + dotState(1:sizeDotState,1) = plasticState(ph)%dotState(:,en) broken = integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) if(broken) exit iteration - broken = plastic_dotState(Delta_t, co,ip,el,ph,me) + broken = plastic_dotState(Delta_t, co,ip,el,ph,en) if(broken) exit iteration - zeta = damper(plasticState(ph)%dotState(:,me),dotState(1:sizeDotState,1),& + zeta = damper(plasticState(ph)%dotState(:,en),dotState(1:sizeDotState,1),& dotState(1:sizeDotState,2)) - plasticState(ph)%dotState(:,me) = plasticState(ph)%dotState(:,me) * zeta & + plasticState(ph)%dotState(:,en) = plasticState(ph)%dotState(:,en) * zeta & + dotState(1:sizeDotState,1) * (1.0_pReal - zeta) - r(1:sizeDotState) = plasticState(ph)%state (1:sizeDotState,me) & + r(1:sizeDotState) = plasticState(ph)%state(1:sizeDotState,en) & - subState0 & - - plasticState(ph)%dotState (1:sizeDotState,me) * Delta_t - plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%state(1:sizeDotState,me) & + - plasticState(ph)%dotState(1:sizeDotState,en) * Delta_t + plasticState(ph)%state(1:sizeDotState,en) = plasticState(ph)%state(1:sizeDotState,en) & - r(1:sizeDotState) - if (converged(r(1:sizeDotState),plasticState(ph)%state(1:sizeDotState,me),plasticState(ph)%atol(1:sizeDotState))) then - broken = plastic_deltaState(ph,me) + if (converged(r(1:sizeDotState),plasticState(ph)%state(1:sizeDotState,en),plasticState(ph)%atol(1:sizeDotState))) then + broken = plastic_deltaState(ph,en) exit iteration endif @@ -714,20 +713,19 @@ function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) resul !-------------------------------------------------------------------------------------------------- !> @brief calculate the damping for correction of state and dot state !-------------------------------------------------------------------------------------------------- - real(pReal) pure function damper(current,previous,previous2) + real(pReal) pure function damper(omega_0,omega_1,omega_2) - real(pReal), dimension(:), intent(in) ::& - current, previous, previous2 + real(pReal), dimension(:), intent(in) :: & + omega_0, omega_1, omega_2 real(pReal) :: dot_prod12, dot_prod22 - dot_prod12 = dot_product(current - previous, previous - previous2) - dot_prod22 = dot_product(previous - previous2, previous - previous2) - if ((dot_product(current,previous) < 0.0_pReal .or. dot_prod12 < 0.0_pReal) .and. dot_prod22 > 0.0_pReal) then - damper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22) - else - damper = 1.0_pReal - endif + dot_prod12 = dot_product(omega_0 - omega_1, omega_1 - omega_2) + dot_prod22 = dot_product(omega_1 - omega_2, omega_1 - omega_2) + + damper = merge(0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22), & + 1.0_pReal, & + (min(dot_product(omega_0,omega_1), dot_prod12) < 0.0_pReal) .and. dot_prod22 > 0.0_pReal) end function damper @@ -751,21 +749,21 @@ function integrateStateEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) res integer :: & ph, & - me, & + en, & sizeDotState ph = material_phaseAt(co,el) - me = material_phaseMemberAt(co,ip,el) + en = material_phaseMemberAt(co,ip,el) - broken = plastic_dotState(Delta_t, co,ip,el,ph,me) + broken = plastic_dotState(Delta_t, co,ip,el,ph,en) if(broken) return sizeDotState = plasticState(ph)%sizeDotState - plasticState(ph)%state(1:sizeDotState,me) = subState0 & - + plasticState(ph)%dotState(1:sizeDotState,me) * Delta_t + plasticState(ph)%state(1:sizeDotState,en) = subState0 & + + plasticState(ph)%dotState(1:sizeDotState,en) * Delta_t - broken = plastic_deltaState(ph,me) + broken = plastic_deltaState(ph,en) if(broken) return broken = integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) @@ -790,34 +788,34 @@ function integrateStateAdaptiveEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip integer :: & ph, & - me, & + en, & sizeDotState real(pReal), dimension(phase_plasticity_maxSizeDotState) :: residuum_plastic ph = material_phaseAt(co,el) - me = material_phaseMemberAt(co,ip,el) + en = material_phaseMemberAt(co,ip,el) - broken = plastic_dotState(Delta_t, co,ip,el,ph,me) + broken = plastic_dotState(Delta_t, co,ip,el,ph,en) if(broken) return sizeDotState = plasticState(ph)%sizeDotState - residuum_plastic(1:sizeDotState) = - plasticState(ph)%dotstate(1:sizeDotState,me) * 0.5_pReal * Delta_t - plasticState(ph)%state(1:sizeDotState,me) = subState0 & - + plasticState(ph)%dotstate(1:sizeDotState,me) * Delta_t + residuum_plastic(1:sizeDotState) = - plasticState(ph)%dotstate(1:sizeDotState,en) * 0.5_pReal * Delta_t + plasticState(ph)%state(1:sizeDotState,en) = subState0 & + + plasticState(ph)%dotstate(1:sizeDotState,en) * Delta_t - broken = plastic_deltaState(ph,me) + broken = plastic_deltaState(ph,en) if(broken) return broken = integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) if(broken) return - broken = plastic_dotState(Delta_t, co,ip,el,ph,me) + broken = plastic_dotState(Delta_t, co,ip,el,ph,en) if(broken) return - broken = .not. converged(residuum_plastic(1:sizeDotState) + 0.5_pReal * plasticState(ph)%dotState(:,me) * Delta_t, & - plasticState(ph)%state(1:sizeDotState,me), & + broken = .not. converged(residuum_plastic(1:sizeDotState) + 0.5_pReal * plasticState(ph)%dotState(:,en) * Delta_t, & + plasticState(ph)%state(1:sizeDotState,en), & plasticState(ph)%atol(1:sizeDotState)) end function integrateStateAdaptiveEuler @@ -908,55 +906,55 @@ function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el,A,B,C,D stage, & ! stage index in integration stage loop n, & ph, & - me, & + en, & sizeDotState real(pReal), dimension(phase_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState ph = material_phaseAt(co,el) - me = material_phaseMemberAt(co,ip,el) + en = material_phaseMemberAt(co,ip,el) - broken = plastic_dotState(Delta_t,co,ip,el,ph,me) + broken = plastic_dotState(Delta_t,co,ip,el,ph,en) if(broken) return sizeDotState = plasticState(ph)%sizeDotState do stage = 1, size(A,1) - plastic_RKdotState(1:sizeDotState,stage) = plasticState(ph)%dotState(:,me) - plasticState(ph)%dotState(:,me) = A(1,stage) * plastic_RKdotState(1:sizeDotState,1) + plastic_RKdotState(1:sizeDotState,stage) = plasticState(ph)%dotState(:,en) + plasticState(ph)%dotState(:,en) = A(1,stage) * plastic_RKdotState(1:sizeDotState,1) do n = 2, stage - plasticState(ph)%dotState(:,me) = plasticState(ph)%dotState(:,me) & + plasticState(ph)%dotState(:,en) = plasticState(ph)%dotState(:,en) & + A(n,stage) * plastic_RKdotState(1:sizeDotState,n) enddo - plasticState(ph)%state(1:sizeDotState,me) = subState0 & - + plasticState(ph)%dotState (1:sizeDotState,me) * Delta_t + plasticState(ph)%state(1:sizeDotState,en) = subState0 & + + plasticState(ph)%dotState (1:sizeDotState,en) * Delta_t broken = integrateStress(F_0 + (F - F_0) * Delta_t * C(stage),subFp0,subFi0,Delta_t * C(stage),co,ip,el) if(broken) exit - broken = plastic_dotState(Delta_t*C(stage),co,ip,el,ph,me) + broken = plastic_dotState(Delta_t*C(stage),co,ip,el,ph,en) if(broken) exit enddo if(broken) return - plastic_RKdotState(1:sizeDotState,size(B)) = plasticState (ph)%dotState(:,me) - plasticState(ph)%dotState(:,me) = matmul(plastic_RKdotState(1:sizeDotState,1:size(B)),B) - plasticState(ph)%state(1:sizeDotState,me) = subState0 & - + plasticState(ph)%dotState (1:sizeDotState,me) * Delta_t + plastic_RKdotState(1:sizeDotState,size(B)) = plasticState (ph)%dotState(:,en) + plasticState(ph)%dotState(:,en) = matmul(plastic_RKdotState(1:sizeDotState,1:size(B)),B) + plasticState(ph)%state(1:sizeDotState,en) = subState0 & + + plasticState(ph)%dotState (1:sizeDotState,en) * Delta_t if(present(DB)) & broken = .not. converged(matmul(plastic_RKdotState(1:sizeDotState,1:size(DB)),DB) * Delta_t, & - plasticState(ph)%state(1:sizeDotState,me), & + plasticState(ph)%state(1:sizeDotState,en), & plasticState(ph)%atol(1:sizeDotState)) if(broken) return - broken = plastic_deltaState(ph,me) + broken = plastic_deltaState(ph,en) if(broken) return broken = integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) @@ -1087,14 +1085,14 @@ end subroutine mechanical_forward !> @brief returns the homogenize elasticity matrix !> ToDo: homogenizedC66 would be more consistent !-------------------------------------------------------------------------------------------------- -module function phase_homogenizedC(ph,me) result(C) +module function phase_homogenizedC(ph,en) result(C) real(pReal), dimension(6,6) :: C - integer, intent(in) :: ph, me + integer, intent(in) :: ph, en plasticType: select case (phase_plasticity(ph)) case (PLASTICITY_DISLOTWIN_ID) plasticType - C = plastic_dislotwin_homogenizedC(ph,me) + C = plastic_dislotwin_homogenizedC(ph,en) case default plasticType C = lattice_C66(1:6,1:6,ph) end select plasticType @@ -1117,7 +1115,7 @@ module function crystallite_stress(dt,co,ip,el) result(converged_) real(pReal) :: & formerSubStep integer :: & - ph, me, sizeDotState + ph, en, sizeDotState logical :: todo real(pReal) :: subFrac,subStep real(pReal), dimension(3,3) :: & @@ -1131,19 +1129,19 @@ module function crystallite_stress(dt,co,ip,el) result(converged_) ph = material_phaseAt(co,el) - me = material_phaseMemberAt(co,ip,el) + en = material_phaseMemberAt(co,ip,el) sizeDotState = plasticState(ph)%sizeDotState - subLi0 = phase_mechanical_Li0(ph)%data(1:3,1:3,me) - subLp0 = phase_mechanical_Lp0(ph)%data(1:3,1:3,me) - subState0 = plasticState(ph)%State0(:,me) + subLi0 = phase_mechanical_Li0(ph)%data(1:3,1:3,en) + subLp0 = phase_mechanical_Lp0(ph)%data(1:3,1:3,en) + subState0 = plasticState(ph)%State0(:,en) if (damageState(ph)%sizeState > 0) & - damageState(ph)%subState0(:,me) = damageState(ph)%state0(:,me) + damageState(ph)%subState0(:,en) = damageState(ph)%state0(:,en) - subFp0 = phase_mechanical_Fp0(ph)%data(1:3,1:3,me) - subFi0 = phase_mechanical_Fi0(ph)%data(1:3,1:3,me) - subF0 = phase_mechanical_F0(ph)%data(1:3,1:3,me) + subFp0 = phase_mechanical_Fp0(ph)%data(1:3,1:3,en) + subFi0 = phase_mechanical_Fi0(ph)%data(1:3,1:3,en) + subF0 = phase_mechanical_F0(ph)%data(1:3,1:3,en) subFrac = 0.0_pReal subStep = 1.0_pReal/num%subStepSizeCryst todo = .true. @@ -1161,29 +1159,29 @@ module function crystallite_stress(dt,co,ip,el) result(converged_) if (todo) then subF0 = subF - subLp0 = phase_mechanical_Lp(ph)%data(1:3,1:3,me) - subLi0 = phase_mechanical_Li(ph)%data(1:3,1:3,me) - subFp0 = phase_mechanical_Fp(ph)%data(1:3,1:3,me) - subFi0 = phase_mechanical_Fi(ph)%data(1:3,1:3,me) - subState0 = plasticState(ph)%state(:,me) + subLp0 = phase_mechanical_Lp(ph)%data(1:3,1:3,en) + subLi0 = phase_mechanical_Li(ph)%data(1:3,1:3,en) + subFp0 = phase_mechanical_Fp(ph)%data(1:3,1:3,en) + subFi0 = phase_mechanical_Fi(ph)%data(1:3,1:3,en) + subState0 = plasticState(ph)%state(:,en) if (damageState(ph)%sizeState > 0) & - damageState(ph)%subState0(:,me) = damageState(ph)%state(:,me) + damageState(ph)%subState0(:,en) = damageState(ph)%state(:,en) endif !-------------------------------------------------------------------------------------------------- ! cut back (reduced time and restore) else subStep = num%subStepSizeCryst * subStep - phase_mechanical_Fp(ph)%data(1:3,1:3,me) = subFp0 - phase_mechanical_Fi(ph)%data(1:3,1:3,me) = subFi0 - phase_mechanical_S(ph)%data(1:3,1:3,me) = phase_mechanical_S0(ph)%data(1:3,1:3,me) ! why no subS0 ? is S0 of any use? + phase_mechanical_Fp(ph)%data(1:3,1:3,en) = subFp0 + phase_mechanical_Fi(ph)%data(1:3,1:3,en) = subFi0 + phase_mechanical_S(ph)%data(1:3,1:3,en) = phase_mechanical_S0(ph)%data(1:3,1:3,en) ! why no subS0 ? is S0 of any use? if (subStep < 1.0_pReal) then ! actual (not initial) cutback - phase_mechanical_Lp(ph)%data(1:3,1:3,me) = subLp0 - phase_mechanical_Li(ph)%data(1:3,1:3,me) = subLi0 + phase_mechanical_Lp(ph)%data(1:3,1:3,en) = subLp0 + phase_mechanical_Li(ph)%data(1:3,1:3,en) = subLi0 endif - plasticState(ph)%state(:,me) = subState0 + plasticState(ph)%state(:,en) = subState0 if (damageState(ph)%sizeState > 0) & - damageState(ph)%state(:,me) = damageState(ph)%subState0(:,me) + damageState(ph)%state(:,en) = damageState(ph)%subState0(:,en) todo = subStep > num%subStepMinCryst ! still on track or already done (beyond repair) endif @@ -1192,7 +1190,7 @@ module function crystallite_stress(dt,co,ip,el) result(converged_) ! prepare for integration if (todo) then subF = subF0 & - + subStep * (phase_mechanical_F(ph)%data(1:3,1:3,me) - phase_mechanical_F0(ph)%data(1:3,1:3,me)) + + subStep * (phase_mechanical_F(ph)%data(1:3,1:3,en) - phase_mechanical_F0(ph)%data(1:3,1:3,en)) converged_ = .not. integrateState(subF0,subF,subFp0,subFi0,subState0(1:sizeDotState),subStep * dt,co,ip,el) converged_ = converged_ .and. .not. integrateDamageState(subStep * dt,co,ip,el) endif @@ -1212,22 +1210,22 @@ module subroutine mechanical_restore(ce,includeL) includeL !< protect agains fake cutback integer :: & - co, ph, me + co, ph, en do co = 1,homogenization_Nconstituents(material_homogenizationID(ce)) ph = material_phaseID(co,ce) - me = material_phaseEntry(co,ce) + en = material_phaseEntry(co,ce) if (includeL) then - phase_mechanical_Lp(ph)%data(1:3,1:3,me) = phase_mechanical_Lp0(ph)%data(1:3,1:3,me) - phase_mechanical_Li(ph)%data(1:3,1:3,me) = phase_mechanical_Li0(ph)%data(1:3,1:3,me) + phase_mechanical_Lp(ph)%data(1:3,1:3,en) = phase_mechanical_Lp0(ph)%data(1:3,1:3,en) + phase_mechanical_Li(ph)%data(1:3,1:3,en) = phase_mechanical_Li0(ph)%data(1:3,1:3,en) endif ! maybe protecting everything from overwriting makes more sense - phase_mechanical_Fp(ph)%data(1:3,1:3,me) = phase_mechanical_Fp0(ph)%data(1:3,1:3,me) - phase_mechanical_Fi(ph)%data(1:3,1:3,me) = phase_mechanical_Fi0(ph)%data(1:3,1:3,me) - phase_mechanical_S(ph)%data(1:3,1:3,me) = phase_mechanical_S0(ph)%data(1:3,1:3,me) + phase_mechanical_Fp(ph)%data(1:3,1:3,en) = phase_mechanical_Fp0(ph)%data(1:3,1:3,en) + phase_mechanical_Fi(ph)%data(1:3,1:3,en) = phase_mechanical_Fi0(ph)%data(1:3,1:3,en) + phase_mechanical_S(ph)%data(1:3,1:3,en) = phase_mechanical_S0(ph)%data(1:3,1:3,en) - plasticState(ph)%state(:,me) = plasticState(ph)%State0(:,me) + plasticState(ph)%state(:,en) = plasticState(ph)%State0(:,en) enddo end subroutine mechanical_restore @@ -1245,7 +1243,7 @@ module function phase_mechanical_dPdF(dt,co,ce) result(dPdF) integer :: & o, & - p, ph, me + p, ph, en real(pReal), dimension(3,3) :: devNull, & invSubFp0,invSubFi0,invFp,invFi, & temp_33_1, temp_33_2, temp_33_3 @@ -1266,20 +1264,20 @@ module function phase_mechanical_dPdF(dt,co,ce) result(dPdF) ph = material_phaseID(co,ce) - me = material_phaseEntry(co,ce) + en = material_phaseEntry(co,ce) call phase_hooke_SandItsTangents(devNull,dSdFe,dSdFi, & - phase_mechanical_Fe(ph)%data(1:3,1:3,me), & - phase_mechanical_Fi(ph)%data(1:3,1:3,me),ph,me) + phase_mechanical_Fe(ph)%data(1:3,1:3,en), & + phase_mechanical_Fi(ph)%data(1:3,1:3,en),ph,en) call phase_LiAndItsTangents(devNull,dLidS,dLidFi, & - phase_mechanical_S(ph)%data(1:3,1:3,me), & - phase_mechanical_Fi(ph)%data(1:3,1:3,me), & - ph,me) + phase_mechanical_S(ph)%data(1:3,1:3,en), & + phase_mechanical_Fi(ph)%data(1:3,1:3,en), & + ph,en) - invFp = math_inv33(phase_mechanical_Fp(ph)%data(1:3,1:3,me)) - invFi = math_inv33(phase_mechanical_Fi(ph)%data(1:3,1:3,me)) - invSubFp0 = math_inv33(phase_mechanical_Fp0(ph)%data(1:3,1:3,me)) - invSubFi0 = math_inv33(phase_mechanical_Fi0(ph)%data(1:3,1:3,me)) + invFp = math_inv33(phase_mechanical_Fp(ph)%data(1:3,1:3,en)) + invFi = math_inv33(phase_mechanical_Fi(ph)%data(1:3,1:3,en)) + invSubFp0 = math_inv33(phase_mechanical_Fp0(ph)%data(1:3,1:3,en)) + invSubFi0 = math_inv33(phase_mechanical_Fi0(ph)%data(1:3,1:3,en)) if (sum(abs(dLidS)) < tol_math_check) then dFidS = 0.0_pReal @@ -1305,15 +1303,15 @@ module function phase_mechanical_dPdF(dt,co,ce) result(dPdF) endif call plastic_LpAndItsTangents(devNull,dLpdS,dLpdFi, & - phase_mechanical_S(ph)%data(1:3,1:3,me), & - phase_mechanical_Fi(ph)%data(1:3,1:3,me),ph,me) + phase_mechanical_S(ph)%data(1:3,1:3,en), & + phase_mechanical_Fi(ph)%data(1:3,1:3,en),ph,en) dLpdS = math_mul3333xx3333(dLpdFi,dFidS) + dLpdS !-------------------------------------------------------------------------------------------------- ! calculate dSdF temp_33_1 = transpose(matmul(invFp,invFi)) - temp_33_2 = matmul(phase_mechanical_F(ph)%data(1:3,1:3,me),invSubFp0) - temp_33_3 = matmul(matmul(phase_mechanical_F(ph)%data(1:3,1:3,me),invFp), invSubFi0) + temp_33_2 = matmul(phase_mechanical_F(ph)%data(1:3,1:3,en),invSubFp0) + temp_33_3 = matmul(matmul(phase_mechanical_F(ph)%data(1:3,1:3,en),invFp), invSubFi0) do o=1,3; do p=1,3 rhs_3333(p,o,1:3,1:3) = matmul(dSdFe(p,o,1:3,1:3),temp_33_1) @@ -1341,9 +1339,9 @@ module function phase_mechanical_dPdF(dt,co,ce) result(dPdF) !-------------------------------------------------------------------------------------------------- ! assemble dPdF - temp_33_1 = matmul(phase_mechanical_S(ph)%data(1:3,1:3,me),transpose(invFp)) - temp_33_2 = matmul(phase_mechanical_F(ph)%data(1:3,1:3,me),invFp) - temp_33_3 = matmul(temp_33_2,phase_mechanical_S(ph)%data(1:3,1:3,me)) + temp_33_1 = matmul(phase_mechanical_S(ph)%data(1:3,1:3,en),transpose(invFp)) + temp_33_2 = matmul(phase_mechanical_F(ph)%data(1:3,1:3,en),invFp) + temp_33_3 = matmul(temp_33_2,phase_mechanical_S(ph)%data(1:3,1:3,en)) dPdF = 0.0_pReal do p=1,3 @@ -1351,7 +1349,7 @@ module function phase_mechanical_dPdF(dt,co,ce) result(dPdF) enddo do o=1,3; do p=1,3 dPdF(1:3,1:3,p,o) = dPdF(1:3,1:3,p,o) & - + matmul(matmul(phase_mechanical_F(ph)%data(1:3,1:3,me),dFpinvdF(1:3,1:3,p,o)),temp_33_1) & + + matmul(matmul(phase_mechanical_F(ph)%data(1:3,1:3,en),dFpinvdF(1:3,1:3,p,o)),temp_33_1) & + matmul(matmul(temp_33_2,dSdF(1:3,1:3,p,o)),transpose(invFp)) & + matmul(temp_33_3,transpose(dFpinvdF(1:3,1:3,p,o))) enddo; enddo @@ -1396,13 +1394,13 @@ end subroutine mechanical_restartRead !---------------------------------------------------------------------------------------------- !< @brief Get first Piola-Kichhoff stress (for use by non-mech physics) !---------------------------------------------------------------------------------------------- -module function mechanical_S(ph,me) result(S) +module function mechanical_S(ph,en) result(S) - integer, intent(in) :: ph,me + integer, intent(in) :: ph,en real(pReal), dimension(3,3) :: S - S = phase_mechanical_S(ph)%data(1:3,1:3,me) + S = phase_mechanical_S(ph)%data(1:3,1:3,en) end function mechanical_S @@ -1410,13 +1408,13 @@ end function mechanical_S !---------------------------------------------------------------------------------------------- !< @brief Get plastic velocity gradient (for use by non-mech physics) !---------------------------------------------------------------------------------------------- -module function mechanical_L_p(ph,me) result(L_p) +module function mechanical_L_p(ph,en) result(L_p) - integer, intent(in) :: ph,me + integer, intent(in) :: ph,en real(pReal), dimension(3,3) :: L_p - L_p = phase_mechanical_Lp(ph)%data(1:3,1:3,me) + L_p = phase_mechanical_Lp(ph)%data(1:3,1:3,en) end function mechanical_L_p @@ -1424,13 +1422,13 @@ end function mechanical_L_p !---------------------------------------------------------------------------------------------- !< @brief Get elastic deformation gradient (for use by non-mech physics) !---------------------------------------------------------------------------------------------- -module function mechanical_F_e(ph,me) result(F_e) +module function mechanical_F_e(ph,en) result(F_e) - integer, intent(in) :: ph,me + integer, intent(in) :: ph,en real(pReal), dimension(3,3) :: F_e - F_e = phase_mechanical_Fe(ph)%data(1:3,1:3,me) + F_e = phase_mechanical_Fe(ph)%data(1:3,1:3,en) end function mechanical_F_e diff --git a/src/phase_mechanical_eigen.f90 b/src/phase_mechanical_eigen.f90 index 7c4e70c1c..8587b2bc8 100644 --- a/src/phase_mechanical_eigen.f90 +++ b/src/phase_mechanical_eigen.f90 @@ -145,10 +145,10 @@ end function kinematics_active2 ! ToDo: MD: S is Mi? !-------------------------------------------------------------------------------------------------- module subroutine phase_LiAndItsTangents(Li, dLi_dS, dLi_dFi, & - S, Fi, ph,me) + S, Fi, ph,en) integer, intent(in) :: & - ph,me + ph,en real(pReal), intent(in), dimension(3,3) :: & S !< 2nd Piola-Kirchhoff stress real(pReal), intent(in), dimension(3,3) :: & @@ -179,7 +179,7 @@ module subroutine phase_LiAndItsTangents(Li, dLi_dS, dLi_dFi, & plasticType: select case (phase_plasticity(ph)) case (PLASTICITY_isotropic_ID) plasticType - call plastic_isotropic_LiAndItsTangent(my_Li, my_dLi_dS, S ,ph,me) + call plastic_isotropic_LiAndItsTangent(my_Li, my_dLi_dS, S ,ph,en) Li = Li + my_Li dLi_dS = dLi_dS + my_dLi_dS active = .true. @@ -188,7 +188,7 @@ module subroutine phase_LiAndItsTangents(Li, dLi_dS, dLi_dFi, & KinematicsLoop: do k = 1, Nmodels(ph) kinematicsType: select case (model(k,ph)) case (KINEMATICS_thermal_expansion_ID) kinematicsType - call thermalexpansion_LiAndItsTangent(my_Li, my_dLi_dS, ph,me) + call thermalexpansion_LiAndItsTangent(my_Li, my_dLi_dS, ph,en) Li = Li + my_Li dLi_dS = dLi_dS + my_dLi_dS active = .true. @@ -197,12 +197,12 @@ module subroutine phase_LiAndItsTangents(Li, dLi_dS, dLi_dFi, & select case (model_damage(ph)) case (KINEMATICS_cleavage_opening_ID) - call damage_anisobrittle_LiAndItsTangent(my_Li, my_dLi_dS, S, ph, me) + call damage_anisobrittle_LiAndItsTangent(my_Li, my_dLi_dS, S, ph, en) Li = Li + my_Li dLi_dS = dLi_dS + my_dLi_dS active = .true. case (KINEMATICS_slipplane_opening_ID) - call damage_isoductile_LiAndItsTangent(my_Li, my_dLi_dS, S, ph, me) + call damage_isoductile_LiAndItsTangent(my_Li, my_dLi_dS, S, ph, en) Li = Li + my_Li dLi_dS = dLi_dS + my_dLi_dS active = .true. diff --git a/src/phase_mechanical_plastic.f90 b/src/phase_mechanical_plastic.f90 index 3e9772a87..3ec275795 100644 --- a/src/phase_mechanical_plastic.f90 +++ b/src/phase_mechanical_plastic.f90 @@ -240,9 +240,9 @@ end subroutine plastic_init ! Mp in, dLp_dMp out !-------------------------------------------------------------------------------------------------- module subroutine plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & - S, Fi, ph,me) + S, Fi, ph,en) integer, intent(in) :: & - ph,me + ph,en real(pReal), intent(in), dimension(3,3) :: & S, & !< 2nd Piola-Kirchhoff stress Fi !< intermediate deformation gradient @@ -250,7 +250,7 @@ module subroutine plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & Lp !< plastic velocity gradient real(pReal), intent(out), dimension(3,3,3,3) :: & dLp_dS, & - dLp_dFi !< derivative me Lp with respect to Fi + dLp_dFi !< derivative en Lp with respect to Fi real(pReal), dimension(3,3,3,3) :: & dLp_dMp !< derivative of Lp with respect to Mandel stress @@ -270,22 +270,22 @@ module subroutine plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & dLp_dMp = 0.0_pReal case (PLASTICITY_ISOTROPIC_ID) plasticType - call isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) + call isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en) case (PLASTICITY_PHENOPOWERLAW_ID) plasticType - call phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) + call phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en) case (PLASTICITY_KINEHARDENING_ID) plasticType - call kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) + call kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en) case (PLASTICITY_NONLOCAL_ID) plasticType - call nonlocal_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,me),ph,me) + call nonlocal_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,en),ph,en) case (PLASTICITY_DISLOTWIN_ID) plasticType - call dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,me),ph,me) + call dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,en),ph,en) case (PLASTICITY_DISLOTUNGSTEN_ID) plasticType - call dislotungsten_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,me),ph,me) + call dislotungsten_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,en),ph,en) end select plasticType @@ -301,14 +301,14 @@ end subroutine plastic_LpAndItsTangents !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -module function plastic_dotState(subdt,co,ip,el,ph,me) result(broken) +module function plastic_dotState(subdt,co,ip,el,ph,en) result(broken) integer, intent(in) :: & co, & !< component-ID of integration point ip, & !< integration point el, & !< element ph, & - me + en real(pReal), intent(in) :: & subdt !< timestep real(pReal), dimension(3,3) :: & @@ -316,30 +316,30 @@ module function plastic_dotState(subdt,co,ip,el,ph,me) result(broken) logical :: broken - Mp = matmul(matmul(transpose(phase_mechanical_Fi(ph)%data(1:3,1:3,me)),& - phase_mechanical_Fi(ph)%data(1:3,1:3,me)),phase_mechanical_S(ph)%data(1:3,1:3,me)) + Mp = matmul(matmul(transpose(phase_mechanical_Fi(ph)%data(1:3,1:3,en)),& + phase_mechanical_Fi(ph)%data(1:3,1:3,en)),phase_mechanical_S(ph)%data(1:3,1:3,en)) plasticType: select case (phase_plasticity(ph)) case (PLASTICITY_ISOTROPIC_ID) plasticType - call isotropic_dotState(Mp,ph,me) + call isotropic_dotState(Mp,ph,en) case (PLASTICITY_PHENOPOWERLAW_ID) plasticType - call phenopowerlaw_dotState(Mp,ph,me) + call phenopowerlaw_dotState(Mp,ph,en) case (PLASTICITY_KINEHARDENING_ID) plasticType - call plastic_kinehardening_dotState(Mp,ph,me) + call plastic_kinehardening_dotState(Mp,ph,en) case (PLASTICITY_DISLOTWIN_ID) plasticType - call dislotwin_dotState(Mp,thermal_T(ph,me),ph,me) + call dislotwin_dotState(Mp,thermal_T(ph,en),ph,en) case (PLASTICITY_DISLOTUNGSTEN_ID) plasticType - call dislotungsten_dotState(Mp,thermal_T(ph,me),ph,me) + call dislotungsten_dotState(Mp,thermal_T(ph,en),ph,en) case (PLASTICITY_NONLOCAL_ID) plasticType - call nonlocal_dotState(Mp,thermal_T(ph,me),subdt,ph,me,ip,el) + call nonlocal_dotState(Mp,thermal_T(ph,en),subdt,ph,en,ip,el) end select plasticType - broken = any(IEEE_is_NaN(plasticState(ph)%dotState(:,me))) + broken = any(IEEE_is_NaN(plasticState(ph)%dotState(:,en))) end function plastic_dotState @@ -383,11 +383,11 @@ end subroutine plastic_dependentState !> @brief for constitutive models having an instantaneous change of state !> will return false if delta state is not needed/supported by the constitutive model !-------------------------------------------------------------------------------------------------- -module function plastic_deltaState(ph, me) result(broken) +module function plastic_deltaState(ph, en) result(broken) integer, intent(in) :: & ph, & - me + en logical :: & broken @@ -398,18 +398,18 @@ module function plastic_deltaState(ph, me) result(broken) mySize - Mp = matmul(matmul(transpose(phase_mechanical_Fi(ph)%data(1:3,1:3,me)),& - phase_mechanical_Fi(ph)%data(1:3,1:3,me)),phase_mechanical_S(ph)%data(1:3,1:3,me)) + Mp = matmul(matmul(transpose(phase_mechanical_Fi(ph)%data(1:3,1:3,en)),& + phase_mechanical_Fi(ph)%data(1:3,1:3,en)),phase_mechanical_S(ph)%data(1:3,1:3,en)) plasticType: select case (phase_plasticity(ph)) case (PLASTICITY_KINEHARDENING_ID) plasticType - call plastic_kinehardening_deltaState(Mp,ph,me) - broken = any(IEEE_is_NaN(plasticState(ph)%deltaState(:,me))) + call plastic_kinehardening_deltaState(Mp,ph,en) + broken = any(IEEE_is_NaN(plasticState(ph)%deltaState(:,en))) case (PLASTICITY_NONLOCAL_ID) plasticType - call plastic_nonlocal_deltaState(Mp,ph,me) - broken = any(IEEE_is_NaN(plasticState(ph)%deltaState(:,me))) + call plastic_nonlocal_deltaState(Mp,ph,en) + broken = any(IEEE_is_NaN(plasticState(ph)%deltaState(:,en))) case default broken = .false. @@ -422,8 +422,8 @@ module function plastic_deltaState(ph, me) result(broken) myOffset = plasticState(ph)%offsetDeltaState mySize = plasticState(ph)%sizeDeltaState - plasticState(ph)%state(myOffset + 1:myOffset + mySize,me) = & - plasticState(ph)%state(myOffset + 1:myOffset + mySize,me) + plasticState(ph)%deltaState(1:mySize,me) + plasticState(ph)%state(myOffset + 1:myOffset + mySize,en) = & + plasticState(ph)%state(myOffset + 1:myOffset + mySize,en) + plasticState(ph)%deltaState(1:mySize,en) end select endif diff --git a/src/phase_mechanical_plastic_dislotwin.f90 b/src/phase_mechanical_plastic_dislotwin.f90 index 43be614ac..b04f28f0e 100644 --- a/src/phase_mechanical_plastic_dislotwin.f90 +++ b/src/phase_mechanical_plastic_dislotwin.f90 @@ -483,10 +483,10 @@ end function plastic_dislotwin_init !-------------------------------------------------------------------------------------------------- !> @brief Return the homogenized elasticity matrix. !-------------------------------------------------------------------------------------------------- -module function plastic_dislotwin_homogenizedC(ph,me) result(homogenizedC) +module function plastic_dislotwin_homogenizedC(ph,en) result(homogenizedC) integer, intent(in) :: & - ph, me + ph, en real(pReal), dimension(6,6) :: & homogenizedC @@ -498,17 +498,17 @@ module function plastic_dislotwin_homogenizedC(ph,me) result(homogenizedC) stt => state(ph)) f_unrotated = 1.0_pReal & - - sum(stt%f_tw(1:prm%sum_N_tw,me)) & - - sum(stt%f_tr(1:prm%sum_N_tr,me)) + - sum(stt%f_tw(1:prm%sum_N_tw,en)) & + - sum(stt%f_tr(1:prm%sum_N_tr,en)) homogenizedC = f_unrotated * prm%C66 do i=1,prm%sum_N_tw homogenizedC = homogenizedC & - + stt%f_tw(i,me)*prm%C66_tw(1:6,1:6,i) + + stt%f_tw(i,en)*prm%C66_tw(1:6,1:6,i) enddo do i=1,prm%sum_N_tr homogenizedC = homogenizedC & - + stt%f_tr(i,me)*prm%C66_tr(1:6,1:6,i) + + stt%f_tr(i,en)*prm%C66_tr(1:6,1:6,i) enddo end associate diff --git a/src/phase_mechanical_plastic_isotropic.f90 b/src/phase_mechanical_plastic_isotropic.f90 index 548e2fd75..d1f191f28 100644 --- a/src/phase_mechanical_plastic_isotropic.f90 +++ b/src/phase_mechanical_plastic_isotropic.f90 @@ -208,7 +208,7 @@ end subroutine isotropic_LpAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief Calculate inelastic velocity gradient and its tangent. !-------------------------------------------------------------------------------------------------- -module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,ph,me) +module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,ph,en) real(pReal), dimension(3,3), intent(out) :: & Li !< inleastic velocity gradient @@ -219,7 +219,7 @@ module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,ph,me) Mi !< Mandel stress integer, intent(in) :: & ph, & - me + en real(pReal) :: & tr !< trace of spherical part of Mandel stress (= 3 x pressure) @@ -232,7 +232,7 @@ module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,ph,me) if (prm%dilatation .and. abs(tr) > 0.0_pReal) then ! no stress or J2 plasticity --> Li and its derivative are zero Li = math_I3 & - * prm%dot_gamma_0/prm%M * (3.0_pReal*prm%M*stt%xi(me))**(-prm%n) & + * prm%dot_gamma_0/prm%M * (3.0_pReal*prm%M*stt%xi(en))**(-prm%n) & * tr * abs(tr)**(prm%n-1.0_pReal) forall (k=1:3,l=1:3,m=1:3,n=1:3) dLi_dMi(k,l,m,n) = prm%n / tr * Li(k,l) * math_I3(m,n) else From 248bc539ccba49471acce25a45a8a80b05d9a462 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 12 Apr 2021 21:38:42 +0200 Subject: [PATCH 180/219] new mappings --- src/homogenization.f90 | 2 +- src/material.f90 | 6 +++--- src/phase_mechanical.f90 | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 3fadf1e96..0d62f83c7 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -297,7 +297,7 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE do co = 1, homogenization_Nconstituents(ho) ph = material_phaseAt(co,el) if (.not. thermal_stress(dt,ph,material_phaseMemberAt(co,ip,el))) then - if (.not. terminallyIll) & ! so first signals terminally ill... + if (.not. terminallyIll) & ! so first signals terminally ill... print*, ' Integration point ', ip,' at element ', el, ' terminally ill' terminallyIll = .true. ! ...and kills all others endif diff --git a/src/material.f90 b/src/material.f90 index 6575872ed..5802ab3c8 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -29,13 +29,13 @@ module material integer, dimension(:), allocatable, public, protected :: & ! (elem) material_homogenizationAt, & !< homogenization ID of each element material_homogenizationID, & !< per cell - material_homogenizationEntry !< cell + material_homogenizationEntry !< per cell integer, dimension(:,:), allocatable :: & ! (ip,elem) material_homogenizationMemberAt !< position of the element within its homogenization instance integer, dimension(:,:), allocatable, public, protected :: & ! (constituent,elem) material_phaseAt, & !< phase ID of each element - material_phaseID, & !< per constituent,cell - material_phaseEntry !< per constituent, cell + material_phaseID, & !< per (constituent,cell) + material_phaseEntry !< per (constituent,cell integer, dimension(:,:,:), allocatable, public, protected :: & ! (constituent,IP,elem) material_phaseMemberAt !< position of the element within its phase instance diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index 6bcfc9a75..83a5082f8 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -226,10 +226,10 @@ module subroutine mechanical_init(materials,phases) allocate(phase_mechanical_P(phases%length)) allocate(phase_mechanical_S0(phases%length)) - allocate(material_orientation0(homogenization_maxNconstituents,phases%length,maxVal(material_phaseMemberAt))) + allocate(material_orientation0(homogenization_maxNconstituents,phases%length,maxVal(material_phaseEntry))) do ph = 1, phases%length - Nmembers = count(material_phaseAt == ph) * discretization_nIPs + Nmembers = count(material_phaseID == ph) allocate(phase_mechanical_Fi(ph)%data(3,3,Nmembers)) allocate(phase_mechanical_Fe(ph)%data(3,3,Nmembers)) From e360e0de5502a28e3fe8e879bd6762a12dbec545 Mon Sep 17 00:00:00 2001 From: Test User Date: Tue, 13 Apr 2021 14:53:31 +0200 Subject: [PATCH 181/219] [skip ci] updated version information after successful test of v3.0.0-alpha2-866-g1be1a72a0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index f8cfbf476..01ac5403c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-839-gc55724d95 +v3.0.0-alpha2-866-g1be1a72a0 From 1762245b69df8a29024d876851e9a585feee4436 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 13 Apr 2021 16:51:59 +0200 Subject: [PATCH 182/219] merge not needed --- src/prec.f90 | 24 ++++++------------------ src/system_routines.f90 | 10 +++++++++- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/prec.f90 b/src/prec.f90 index 1a96c75a9..a81a3ee27 100644 --- a/src/prec.f90 +++ b/src/prec.f90 @@ -108,17 +108,13 @@ logical elemental pure function dEq(a,b,tol) real(pReal), intent(in) :: a,b real(pReal), intent(in), optional :: tol - real(pReal) :: eps - if (present(tol)) then - eps = tol + dEq = abs(a-b) <= tol else - eps = PREAL_EPSILON * maxval(abs([a,b])) + dEq = abs(a-b) <= PREAL_EPSILON * maxval(abs([a,b])) endif - dEq = merge(.True.,.False.,abs(a-b) <= eps) - end function dEq @@ -150,17 +146,13 @@ logical elemental pure function dEq0(a,tol) real(pReal), intent(in) :: a real(pReal), intent(in), optional :: tol - real(pReal) :: eps - if (present(tol)) then - eps = tol + dEq0 = abs(a) <= tol else - eps = PREAL_MIN * 10.0_pReal + dEq0 = abs(a) <= PREAL_MIN * 10.0_pReal endif - dEq0 = merge(.True.,.False.,abs(a) <= eps) - end function dEq0 @@ -193,17 +185,13 @@ logical elemental pure function cEq(a,b,tol) complex(pReal), intent(in) :: a,b real(pReal), intent(in), optional :: tol - real(pReal) :: eps - if (present(tol)) then - eps = tol + cEq = abs(a-b) <= tol else - eps = PREAL_EPSILON * maxval(abs([a,b])) + cEq = abs(a-b) <= PREAL_EPSILON * maxval(abs([a,b])) endif - cEq = merge(.True.,.False.,abs(a-b) <= eps) - end function cEq diff --git a/src/system_routines.f90 b/src/system_routines.f90 index 309b96b7e..7a4e41a57 100644 --- a/src/system_routines.f90 +++ b/src/system_routines.f90 @@ -83,7 +83,8 @@ logical function setCWD(path) character(len=*), intent(in) :: path - setCWD=merge(.True.,.False.,setCWD_C(f_c_string(path)) /= 0_C_INT) + + setCWD = setCWD_C(f_c_string(path)) /= 0_C_INT end function setCWD @@ -98,6 +99,7 @@ function getCWD() character(kind=C_CHAR), dimension(pPathLen+1) :: getCWD_Cstring integer(C_INT) :: stat + call getCWD_C(getCWD_Cstring,stat) if(stat == 0) then @@ -119,6 +121,7 @@ function getHostName() character(kind=C_CHAR), dimension(pStringLen+1) :: getHostName_Cstring integer(C_INT) :: stat + call getHostName_C(getHostName_Cstring,stat) if(stat == 0) then @@ -140,6 +143,7 @@ function getUserName() character(kind=C_CHAR), dimension(pStringLen+1) :: getUserName_Cstring integer(C_INT) :: stat + call getUserName_C(getUserName_Cstring,stat) if(stat == 0) then @@ -159,8 +163,10 @@ pure function c_f_string(c_string) result(f_string) character(kind=C_CHAR), dimension(:), intent(in) :: c_string character(len=:), allocatable :: f_string + integer :: i + allocate(character(len=size(c_string))::f_string) arrayToString: do i=1,len(f_string) if (c_string(i) /= C_NULL_CHAR) then @@ -182,8 +188,10 @@ pure function f_c_string(f_string) result(c_string) character(len=*), intent(in) :: f_string character(kind=C_CHAR), dimension(len_trim(f_string)+1) :: c_string + integer :: i + do i=1,len_trim(f_string) c_string(i)=f_string(i:i) enddo From 285889b48e65792336ca2d5b229e331898126ea8 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 13 Apr 2021 21:30:56 +0200 Subject: [PATCH 183/219] merge evaluates both expression, can lead to division by zero --- src/phase_damage.f90 | 14 +++++++------- src/phase_mechanical.f90 | 12 +++++++----- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index 8df2cd5e4..6d2243933 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -257,20 +257,20 @@ module function integrateDamageState(dt,co,ip,el) result(broken) contains - !-------------------------------------------------------------------------------------------------- !> @brief calculate the damping for correction of state and dot state !-------------------------------------------------------------------------------------------------- - real(pReal) pure function damper(current,previous,previous2) + real(pReal) pure function damper(omega_0,omega_1,omega_2) - real(pReal), dimension(:), intent(in) ::& - current, previous, previous2 + real(pReal), dimension(:), intent(in) :: & + omega_0, omega_1, omega_2 real(pReal) :: dot_prod12, dot_prod22 - dot_prod12 = dot_product(current - previous, previous - previous2) - dot_prod22 = dot_product(previous - previous2, previous - previous2) - if ((dot_product(current,previous) < 0.0_pReal .or. dot_prod12 < 0.0_pReal) .and. dot_prod22 > 0.0_pReal) then + dot_prod12 = dot_product(omega_0-omega_1, omega_1-omega_2) + dot_prod22 = dot_product(omega_1-omega_2, omega_1-omega_2) + + if (min(dot_product(omega_0,omega_1),dot_prod12) < 0.0_pReal .and. dot_prod22 > 0.0_pReal) then damper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22) else damper = 1.0_pReal diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index 83a5082f8..298ff57f3 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -720,12 +720,14 @@ function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) resul real(pReal) :: dot_prod12, dot_prod22 - dot_prod12 = dot_product(omega_0 - omega_1, omega_1 - omega_2) - dot_prod22 = dot_product(omega_1 - omega_2, omega_1 - omega_2) + dot_prod12 = dot_product(omega_0-omega_1, omega_1-omega_2) + dot_prod22 = dot_product(omega_1-omega_2, omega_1-omega_2) - damper = merge(0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22), & - 1.0_pReal, & - (min(dot_product(omega_0,omega_1), dot_prod12) < 0.0_pReal) .and. dot_prod22 > 0.0_pReal) + if (min(dot_product(omega_0,omega_1),dot_prod12) < 0.0_pReal .and. dot_prod22 > 0.0_pReal) then + damper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22) + else + damper = 1.0_pReal + endif end function damper From 0e6cb127df761fae00a308f846b51201b5671d16 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 14 Apr 2021 19:24:45 +0200 Subject: [PATCH 184/219] damage can be defined in parts of the domain ... --- python/damask/_result.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 667a89c87..96e76374a 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -329,7 +329,7 @@ class Result: for inc in self.visible['increments']: for ty in ['phase','homogenization']: for label in self.visible[ty+'s']: - for field in self.visible['fields']: + for field in _match(self.visible['fields'],f['/'.join([inc,ty,label])].keys()): path_old = '/'.join([inc,ty,label,field,name_old]) path_new = '/'.join([inc,ty,label,field,name_new]) if path_old in f.keys(): @@ -352,7 +352,7 @@ class Result: msg = ' '.join([msg,f'{ty}\n']) for label in self.visible[ty+'s']: msg = ' '.join([msg,f'{label}\n']) - for field in self.visible['fields']: + for field in _match(self.visible['fields'],f['/'.join([inc,ty,label])].keys()): msg = ' '.join([msg,f'{field}\n']) for d in f['/'.join([inc,ty,label,field])].keys(): dataset = f['/'.join([inc,ty,label,field,d])] @@ -962,7 +962,7 @@ class Result: for inc in self.visible['increments']: for ty in ['phase','homogenization']: for label in self.visible[ty+'s']: - for field in self.visible['fields']: + for field in _match(self.visible['fields'],f['/'.join([inc,ty,label])].keys()): group = '/'.join([inc,ty,label,field]) if set(datasets.values()).issubset(f[group].keys()): groups.append(group) @@ -1098,7 +1098,7 @@ class Result: for ty in ['phase','homogenization']: for label in self.visible[ty+'s']: - for field in self.visible['fields']: + for field in _match(self.visible['fields'],f['/'.join([inc,ty,label])].keys()): for out in _match(output,f['/'.join([inc,ty,label,field])].keys()): name = '/'.join([inc,ty,label,field,out]) shape = f[name].shape[1:] From 34dc4fda13fafef87000465af1dc5096899814fd Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 14 Apr 2021 19:58:58 +0200 Subject: [PATCH 185/219] needs rework --- src/commercialFEM_fileList.f90 | 1 - src/phase_damage.f90 | 25 +----- src/phase_damage_anisoductile.f90 | 138 ------------------------------ 3 files changed, 2 insertions(+), 162 deletions(-) delete mode 100644 src/phase_damage_anisoductile.f90 diff --git a/src/commercialFEM_fileList.f90 b/src/commercialFEM_fileList.f90 index 1eac4f8fc..5ddc7219e 100644 --- a/src/commercialFEM_fileList.f90 +++ b/src/commercialFEM_fileList.f90 @@ -40,7 +40,6 @@ #include "phase_damage_isobrittle.f90" #include "phase_damage_isoductile.f90" #include "phase_damage_anisobrittle.f90" -#include "phase_damage_anisoductile.f90" #include "homogenization.f90" #include "homogenization_mechanical.f90" #include "homogenization_mechanical_pass.f90" diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index 6d2243933..5a1d5970b 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -12,8 +12,7 @@ submodule(phase) damage DAMAGE_UNDEFINED_ID, & DAMAGE_ISOBRITTLE_ID, & DAMAGE_ISODUCTILE_ID, & - DAMAGE_ANISOBRITTLE_ID, & - DAMAGE_ANISODUCTILE_ID + DAMAGE_ANISOBRITTLE_ID end enum @@ -34,10 +33,6 @@ submodule(phase) damage logical, dimension(:), allocatable :: mySources end function anisobrittle_init - module function anisoductile_init() result(mySources) - logical, dimension(:), allocatable :: mySources - end function anisoductile_init - module function isobrittle_init() result(mySources) logical, dimension(:), allocatable :: mySources end function isobrittle_init @@ -62,10 +57,6 @@ submodule(phase) damage S end subroutine anisobrittle_dotState - module subroutine anisoductile_dotState(ph,me) - integer, intent(in) :: ph,me - end subroutine anisoductile_dotState - module subroutine isoductile_dotState(ph,me) integer, intent(in) :: ph,me end subroutine isoductile_dotState @@ -75,11 +66,6 @@ submodule(phase) damage character(len=*), intent(in) :: group end subroutine anisobrittle_results - module subroutine anisoductile_results(phase,group) - integer, intent(in) :: phase - character(len=*), intent(in) :: group - end subroutine anisoductile_results - module subroutine isobrittle_results(phase,group) integer, intent(in) :: phase character(len=*), intent(in) :: group @@ -146,7 +132,6 @@ module subroutine damage_init where(isobrittle_init() ) phase_source = DAMAGE_ISOBRITTLE_ID where(isoductile_init() ) phase_source = DAMAGE_ISODUCTILE_ID where(anisobrittle_init()) phase_source = DAMAGE_ANISOBRITTLE_ID - where(anisoductile_init()) phase_source = DAMAGE_ANISODUCTILE_ID endif end subroutine damage_init @@ -171,7 +156,7 @@ module function phase_f_phi(phi,co,ce) result(f) en = material_phaseEntry(co,ce) select case(phase_source(ph)) - case(DAMAGE_ISOBRITTLE_ID,DAMAGE_ISODUCTILE_ID,DAMAGE_ANISOBRITTLE_ID,DAMAGE_ANISODUCTILE_ID) + case(DAMAGE_ISOBRITTLE_ID,DAMAGE_ISODUCTILE_ID,DAMAGE_ANISOBRITTLE_ID) f = 1.0_pReal & - phi*damageState(ph)%state(1,en) case default @@ -304,9 +289,6 @@ module subroutine damage_results(group,ph) case (DAMAGE_ANISOBRITTLE_ID) sourceType call anisobrittle_results(ph,group//'damage/') - case (DAMAGE_ANISODUCTILE_ID) sourceType - call anisoductile_results(ph,group//'damage/') - end select sourceType end subroutine damage_results @@ -332,9 +314,6 @@ function phase_damage_collectDotState(ph,me) result(broken) case (DAMAGE_ISODUCTILE_ID) sourceType call isoductile_dotState(ph,me) - case (DAMAGE_ANISODUCTILE_ID) sourceType - call anisoductile_dotState(ph,me) - case (DAMAGE_ANISOBRITTLE_ID) sourceType call anisobrittle_dotState(mechanical_S(ph,me), ph,me) ! correct stress? diff --git a/src/phase_damage_anisoductile.f90 b/src/phase_damage_anisoductile.f90 deleted file mode 100644 index 049f148bc..000000000 --- a/src/phase_damage_anisoductile.f90 +++ /dev/null @@ -1,138 +0,0 @@ -!-------------------------------------------------------------------------------------------------- -!> @author Luv Sharma, Max-Planck-Institut für Eisenforschung GmbH -!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH -!> @brief material subroutine incorporating anisotropic ductile damage source mechanism -!> @details to be done -!-------------------------------------------------------------------------------------------------- -submodule(phase:damage) anisoductile - - type :: tParameters !< container type for internal constitutive parameters - real(pReal) :: & - q !< damage rate sensitivity - real(pReal), dimension(:), allocatable :: & - gamma_crit !< critical plastic strain per slip system - character(len=pStringLen), allocatable, dimension(:) :: & - output - end type tParameters - - type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters - -contains - - -!-------------------------------------------------------------------------------------------------- -!> @brief module initialization -!> @details reads in material parameters, allocates arrays, and does sanity checks -!-------------------------------------------------------------------------------------------------- -module function anisoductile_init() result(mySources) - - logical, dimension(:), allocatable :: mySources - - class(tNode), pointer :: & - phases, & - phase, & - mech, & - pl, & - sources, & - src - integer :: Ninstances,Nmembers,ph - integer, dimension(:), allocatable :: N_sl - character(len=pStringLen) :: extmsg = '' - - - mySources = source_active('anisoductile') - if(count(mySources) == 0) return - - print'(/,a)', ' <<<+- phase:damage:anisoductile init -+>>>' - print'(a,i0)', ' # phases: ',count(mySources); flush(IO_STDOUT) - - - phases => config_material%get('phase') - allocate(param(phases%length)) - - do ph = 1, phases%length - if(mySources(ph)) then - phase => phases%get(ph) - mech => phase%get('mechanical') - pl => mech%get('plastic') - sources => phase%get('damage') - - - associate(prm => param(ph)) - src => sources%get(1) - - N_sl = pl%get_as1dInt('N_sl',defaultVal=emptyIntArray) - prm%q = src%get_asFloat('q') - prm%gamma_crit = src%get_as1dFloat('gamma_crit',requiredSize=size(N_sl)) - - ! expand: family => system - prm%gamma_crit = math_expand(prm%gamma_crit,N_sl) - -#if defined (__GFORTRAN__) - prm%output = output_as1dString(src) -#else - prm%output = src%get_as1dString('output',defaultVal=emptyStringArray) -#endif - - ! sanity checks - if (prm%q <= 0.0_pReal) extmsg = trim(extmsg)//' q' - if (any(prm%gamma_crit < 0.0_pReal)) extmsg = trim(extmsg)//' gamma_crit' - - Nmembers=count(material_phaseID==ph) - call phase_allocateState(damageState(ph),Nmembers,1,1,0) - damageState(ph)%atol = src%get_asFloat('anisoDuctile_atol',defaultVal=1.0e-3_pReal) - if(any(damageState(ph)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' anisoductile_atol' - - end associate - -!-------------------------------------------------------------------------------------------------- -! exit if any parameter is out of range - if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(damage_anisoDuctile)') - endif - - enddo - - -end function anisoductile_init - - -!-------------------------------------------------------------------------------------------------- -!> @brief calculates derived quantities from state -!-------------------------------------------------------------------------------------------------- -module subroutine anisoductile_dotState(ph,me) - - integer, intent(in) :: & - ph, & - me - - - associate(prm => param(ph)) - damageState(ph)%dotState(1,me) = sum(plasticState(ph)%slipRate(:,me)/(damage_phi(ph,me)**prm%q)/prm%gamma_crit) - end associate - -end subroutine anisoductile_dotState - - -!-------------------------------------------------------------------------------------------------- -!> @brief writes results to HDF5 output file -!-------------------------------------------------------------------------------------------------- -module subroutine anisoductile_results(phase,group) - - integer, intent(in) :: phase - character(len=*), intent(in) :: group - - integer :: o - - - associate(prm => param(phase), stt => damageState(phase)%state) - outputsLoop: do o = 1,size(prm%output) - select case(trim(prm%output(o))) - case ('f_phi') - call results_writeDataset(group,stt,trim(prm%output(o)),'driving force','J/m³') - end select - enddo outputsLoop - end associate - -end subroutine anisoductile_results - -end submodule anisoductile From 190ddafa446812d799d05a79f16362890970e459 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 14 Apr 2021 07:06:24 +0200 Subject: [PATCH 186/219] don't support old file formats --- python/damask/_result.py | 69 +++++++++++++++------------------------- 1 file changed, 25 insertions(+), 44 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 667a89c87..86c488416 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -79,34 +79,25 @@ class Result: self.version_major = f.attrs['DADF5_version_major'] self.version_minor = f.attrs['DADF5_version_minor'] - if self.version_major != 0 or not 7 <= self.version_minor <= 12: + if self.version_major != 0 or not 12 <= self.version_minor <= 12: raise TypeError(f'Unsupported DADF5 version {self.version_major}.{self.version_minor}') - self.structured = 'grid' in f['geometry'].attrs.keys() or \ - 'cells' in f['geometry'].attrs.keys() + self.structured = 'cells' in f['geometry'].attrs.keys() if self.structured: - try: - self.cells = f['geometry'].attrs['cells'] - except KeyError: - self.cells = f['geometry'].attrs['grid'] + self.cells = f['geometry'].attrs['cells'] self.size = f['geometry'].attrs['size'] self.origin = f['geometry'].attrs['origin'] - r=re.compile('inc[0-9]+' if self.version_minor < 12 else 'increment_[0-9]+') + r=re.compile('increment_[0-9]+') self.increments = sorted([i for i in f.keys() if r.match(i)],key=util.natural_sort) - self.times = [round(f[i].attrs['time/s' if self.version_minor < 12 else - 't/s'],12) for i in self.increments] + self.times = [round(f[i].attrs['t/s'],12) for i in self.increments] - grp = 'mapping' if self.version_minor < 12 else 'cell_to' + self.N_materialpoints, self.N_constituents = np.shape(f[f'cell_to/phase']) - self.N_materialpoints, self.N_constituents = np.shape(f[f'{grp}/phase']) - - self.homogenizations = [m.decode() for m in np.unique(f[f'{grp}/homogenization'] - ['Name' if self.version_minor < 12 else 'label'])] + self.homogenizations = [m.decode() for m in np.unique(f[f'cell_to/homogenization']['label'])] self.homogenizations = sorted(self.homogenizations,key=util.natural_sort) - self.phases = [c.decode() for c in np.unique(f[f'{grp}/phase'] - ['Name' if self.version_minor < 12 else 'label'])] + self.phases = [c.decode() for c in np.unique(f[f'cell_to/phase']['label'])] self.phases = sorted(self.phases,key=util.natural_sort) self.fields = [] @@ -172,10 +163,9 @@ class Result: choice = list(datasets).copy() if hasattr(datasets,'__iter__') and not isinstance(datasets,str) else \ [datasets] - inc = 'inc' if self.version_minor < 12 else 'increment_' # compatibility hack if what == 'increments': - choice = [c if isinstance(c,str) and c.startswith(inc) else - f'{inc}{c}' for c in choice] + choice = [c if isinstance(c,str) and c.startswith('increment_') else + f'increment_{c}' for c in choice] elif what == 'times': what = 'increments' if choice == ['*']: @@ -233,11 +223,9 @@ class Result: End increment. """ - # compatibility hack - ln = 3 if self.version_minor < 12 else 10 selected = [] - for i,inc in enumerate([int(i[ln:]) for i in self.increments]): - s,e = map(lambda x: int(x[ln:] if isinstance(x,str) and x.startswith('inc') else x), (start,end)) + for i,inc in enumerate([int(i[10:]) for i in self.increments]): + s,e = map(lambda x: int(x[10:] if isinstance(x,str) and x.startswith('inc') else x), (start,end)) if s <= inc <= e: selected.append(self.increments[i]) return selected @@ -341,9 +329,6 @@ class Result: def list_data(self): """Return information on all active datasets in the file.""" - # compatibility hack - de = 'Description' if self.version_minor < 12 else 'description' - un = 'Unit' if self.version_minor < 12 else 'unit' msg = '' with h5py.File(self.fname,'r') as f: for inc in self.visible['increments']: @@ -356,10 +341,10 @@ class Result: msg = ' '.join([msg,f'{field}\n']) for d in f['/'.join([inc,ty,label,field])].keys(): dataset = f['/'.join([inc,ty,label,field,d])] - unit = f' / {dataset.attrs[un]}' if h5py3 else \ - f' / {dataset.attrs[un].decode()}' - description = dataset.attrs[de] if h5py3 else \ - dataset.attrs[de].decode() + unit = f' / {dataset.attrs["unit"]}' if h5py3 else \ + f' / {dataset.attrs["unit"].decode()}' + description = dataset.attrs['description'] if h5py3 else \ + dataset.attrs['description'].decode() msg = ' '.join([msg,f'{d}{unit}: {description}\n']) return msg @@ -1023,7 +1008,6 @@ class Result: Defaults to '*', in which case all datasets are considered. """ - u = 'Unit' if self.version_minor < 12 else 'unit' # compatibility hack if self.N_constituents != 1 or len(self.phases) != 1 or not self.structured: raise TypeError('XDMF output requires structured grid with single phase and single constituent.') @@ -1104,7 +1088,8 @@ class Result: shape = f[name].shape[1:] dtype = f[name].dtype - unit = f[name].attrs[u] if h5py3 else f[name].attrs[u].decode() + unit = f[name].attrs['unit'] if h5py3 else \ + f[name].attrs['unit'].decode() attributes.append(ET.SubElement(grid, 'Attribute')) attributes[-1].attrib = {'Name': '/'.join([ty,field,out])+f' / {unit}', @@ -1123,23 +1108,20 @@ class Result: def _mappings(self): - grp = 'mapping' if self.version_minor < 12 else 'cell_to' # compatibility hack - name = 'Name' if self.version_minor < 12 else 'label' # compatibility hack - member = 'member' if self.version_minor < 12 else 'entry' # compatibility hack - + """Mappings to place data spatially.""" with h5py.File(self.fname,'r') as f: at_cell_ph = [] in_data_ph = [] for c in range(self.N_constituents): - at_cell_ph.append({label: np.where(f['/'.join([grp,'phase'])][:,c][name] == label.encode())[0] \ + at_cell_ph.append({label: np.where(f['/'.join(['cell_to','phase'])][:,c]['label'] == label.encode())[0] \ for label in self.visible['phases']}) - in_data_ph.append({label: f['/'.join([grp,'phase'])][member][at_cell_ph[c][label]][:,c] \ + in_data_ph.append({label: f['/'.join(['cell_to','phase'])]['entry'][at_cell_ph[c][label]][:,c] \ for label in self.visible['phases']}) - at_cell_ho = {label: np.where(f['/'.join([grp,'homogenization'])][:][name] == label.encode())[0] \ + at_cell_ho = {label: np.where(f['/'.join(['cell_to','homogenization'])][:]['label'] == label.encode())[0] \ for label in self.visible['homogenizations']} - in_data_ho = {label: f['/'.join([grp,'homogenization'])][member][at_cell_ho[label]] \ + in_data_ho = {label: f['/'.join(['cell_to','homogenization'])]['entry'][at_cell_ho[label]] \ for label in self.visible['homogenizations']} return at_cell_ph,in_data_ph,at_cell_ho,in_data_ho @@ -1176,8 +1158,7 @@ class Result: elif mode.lower()=='point': v = VTK.from_poly_data(self.coordinates0_point) - ln = 3 if self.version_minor < 12 else 10 # compatibility hack - N_digits = int(np.floor(np.log10(max(1,int(self.increments[-1][ln:])))))+1 + N_digits = int(np.floor(np.log10(max(1,int(self.increments[-1][10:])))))+1 constituents_ = constituents if isinstance(constituents,Iterable) else \ (range(self.N_constituents) if constituents is None else [constituents]) @@ -1221,7 +1202,7 @@ class Result: for label,dataset in outs.items(): v.add(dataset,' / '.join(['/'.join([ty,field,label]),dataset.dtype.metadata['unit']])) - v.save(f'{self.fname.stem}_inc{inc[ln:].zfill(N_digits)}',parallel=parallel) + v.save(f'{self.fname.stem}_inc{inc[10:].zfill(N_digits)}',parallel=parallel) def get(self,output='*',flatten=True,prune=True): From d83c746a175179432e4b9ff05ab98ae7aee74e35 Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Thu, 15 Apr 2021 12:07:33 +0200 Subject: [PATCH 187/219] polishing --- src/material.f90 | 2 +- src/phase_thermal.f90 | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/material.f90 b/src/material.f90 index 5802ab3c8..add9fd1c3 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -35,7 +35,7 @@ module material integer, dimension(:,:), allocatable, public, protected :: & ! (constituent,elem) material_phaseAt, & !< phase ID of each element material_phaseID, & !< per (constituent,cell) - material_phaseEntry !< per (constituent,cell + material_phaseEntry !< per (constituent,cell) integer, dimension(:,:,:), allocatable, public, protected :: & ! (constituent,IP,elem) material_phaseMemberAt !< position of the element within its phase instance diff --git a/src/phase_thermal.f90 b/src/phase_thermal.f90 index f6d046266..b51ac74f5 100644 --- a/src/phase_thermal.f90 +++ b/src/phase_thermal.f90 @@ -190,7 +190,7 @@ end function phase_thermal_collectDotState !-------------------------------------------------------------------------------------------------- -!> @brief Damage viscosity. +!> @brief Thermal viscosity. !-------------------------------------------------------------------------------------------------- module function phase_mu_T(co,ce) result(mu) @@ -205,7 +205,7 @@ end function phase_mu_T !-------------------------------------------------------------------------------------------------- -!> @brief Damage conductivity/diffusivity in reference configuration. +!> @brief Thermal conductivity/diffusivity in reference configuration. !-------------------------------------------------------------------------------------------------- module function phase_K_T(co,ce) result(K) From 5b96a69c71d0a1f2a7964baad37242e442076aaa Mon Sep 17 00:00:00 2001 From: Test User Date: Thu, 15 Apr 2021 16:17:42 +0200 Subject: [PATCH 188/219] [skip ci] updated version information after successful test of v3.0.0-alpha2-875-gd83c746a1 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 01ac5403c..61a4c45f3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-866-g1be1a72a0 +v3.0.0-alpha2-875-gd83c746a1 From 6a66ace28dd67066f7bb938829749bf088767efe Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 15 Apr 2021 16:35:53 +0200 Subject: [PATCH 189/219] preparing third 3.0 series alpha release --- PRIVATE | 2 +- VERSION | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PRIVATE b/PRIVATE index 1490f9741..23eac08c9 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 1490f97417664d6ae11d7ceafb6b98c9cc2dade1 +Subproject commit 23eac08c9f9638f8dae76710095222d00f948eec diff --git a/VERSION b/VERSION index 61a4c45f3..048b75093 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-875-gd83c746a1 +v3.0.0-alpha3 From 7eefc87e5a0aef4a26cd5547286c8c55abd3c35e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 20 Apr 2021 14:44:15 +0200 Subject: [PATCH 190/219] ignore files for language detection (old syntax was wrong) --- .gitattributes | 8 ++++++-- .gitlab-ci.yml | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitattributes b/.gitattributes index 1437f7412..05b249328 100644 --- a/.gitattributes +++ b/.gitattributes @@ -12,8 +12,12 @@ *.pbz2 binary # ignore files from MSC.Marc in language statistics -installation/mods_MarcMentat/20*/* linguist-vendored +installation/mods_MarcMentat/** linguist-vendored src/Marc/include/* linguist-vendored +installation/mods_MarcMentat/apply_DAMASK_modifications.py linguist-vendored=false # ignore reference files for tests in language statistics -python/tests/reference/* linguist-vendored +python/tests/reference/** linguist-vendored + +# ignore deprecated scripts +processing/legacy/** linguist-vendored diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9df1e9330..7cb954631 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -233,7 +233,7 @@ source_distribution: stage: deploy script: - cd $(mktemp -d) - - $DAMASKROOT/PRIVATE/releasing/deployMe.sh $CI_COMMIT_SHA + - $DAMASKROOT/PRIVATE/releasing/deploy.sh $CI_COMMIT_SHA except: - master - release From d0dd1fd83b53a98b05f53bfdb879aceb60f8a759 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 20 Apr 2021 17:43:03 +0200 Subject: [PATCH 191/219] new deploy syntax --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7cb954631..3228d8db6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -233,7 +233,7 @@ source_distribution: stage: deploy script: - cd $(mktemp -d) - - $DAMASKROOT/PRIVATE/releasing/deploy.sh $CI_COMMIT_SHA + - $DAMASKROOT/PRIVATE/releasing/deploy.sh $DAMASKROOT $CI_COMMIT_SHA except: - master - release From bf25250667878776bb73ce52160e8061dc866316 Mon Sep 17 00:00:00 2001 From: Test User Date: Tue, 20 Apr 2021 23:16:02 +0200 Subject: [PATCH 192/219] [skip ci] updated version information after successful test of v3.0.0-alpha3-2-gd0dd1fd83 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 048b75093..543799db9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha3 +v3.0.0-alpha3-2-gd0dd1fd83 From 3f8bd645d8514ac0cf9a9bbd36fdc1ac32e94037 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 22 Apr 2021 07:55:41 +0200 Subject: [PATCH 193/219] handle the case that MSC-related variables are not set --- python/damask/solver/_marc.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/python/damask/solver/_marc.py b/python/damask/solver/_marc.py index 9fb07fc1c..a6707efd9 100644 --- a/python/damask/solver/_marc.py +++ b/python/damask/solver/_marc.py @@ -4,10 +4,13 @@ import re import os from pathlib import Path +_default_version='2020' +_default_path='/opt/msc' + class Marc: """Wrapper to run DAMASK with MSCMarc.""" - def __init__(self,version=os.environ['MSC_VERSION']): + def __init__(self,version=os.environ.get('MSC_VERSION',_default_version)): """ Create a Marc solver object. @@ -17,13 +20,12 @@ class Marc: Marc version """ - self.solver = 'Marc' self.version = version @property def library_path(self): - path_lib = Path(f'{os.environ["MSC_ROOT"]}/mentat{self.version}/shlib/linux64') + path_lib = Path(f'{os.environ.get("MSC_ROOT",_default_path)}/mentat{self.version}/shlib/linux64') if not path_lib.is_dir(): raise FileNotFoundError(f'library path "{path_lib}" not found') @@ -33,7 +35,7 @@ class Marc: @property def tools_path(self): - path_tools = Path(f'{os.environ["MSC_ROOT"]}/marc{self.version}/tools') + path_tools = Path(f'{os.environ.get("MSC_ROOT",_default_path)}/marc{self.version}/tools') if not path_tools.is_dir(): raise FileNotFoundError(f'tools path "{path_tools}" not found') From 74dd9bf58919635a8307d9ba10bcfdf8f8e0c1c5 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 22 Apr 2021 08:04:02 +0200 Subject: [PATCH 194/219] use sensible defaults if shell NUM_THREADS is not given --- src/parallelization.f90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parallelization.f90 b/src/parallelization.f90 index 8413ba825..e850ff04d 100644 --- a/src/parallelization.f90 +++ b/src/parallelization.f90 @@ -84,13 +84,13 @@ subroutine parallelization_init !$ call get_environment_variable(name='OMP_NUM_THREADS',value=NumThreadsString,STATUS=got_env) !$ if(got_env /= 0) then -!$ print*, 'Could not determine value of $OMP_NUM_THREADS' -!$ OMP_NUM_THREADS = 1_pI32 +!$ print*, 'Could not get $OMP_NUM_THREADS, using default' +!$ OMP_NUM_THREADS = 4_pI32 !$ else !$ read(NumThreadsString,'(i6)') OMP_NUM_THREADS !$ if (OMP_NUM_THREADS < 1_pI32) then -!$ print*, 'Invalid OMP_NUM_THREADS: '//trim(NumThreadsString) -!$ OMP_NUM_THREADS = 1_pI32 +!$ print*, 'Invalid OMP_NUM_THREADS: "'//trim(NumThreadsString)//'", using default' +!$ OMP_NUM_THREADS = 4_pI32 !$ endif !$ endif !$ print'(a,i2)', ' OMP_NUM_THREADS: ',OMP_NUM_THREADS From 0773fb5fae16daac21c6bad3af9a1d672196d5c3 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 22 Apr 2021 08:04:46 +0200 Subject: [PATCH 195/219] KISS setting shell variables directly is more verbose --- env/CONFIG | 5 ----- env/DAMASK.sh | 11 ----------- env/DAMASK.zsh | 13 ------------- 3 files changed, 29 deletions(-) delete mode 100644 env/CONFIG diff --git a/env/CONFIG b/env/CONFIG deleted file mode 100644 index 4407f4d2b..000000000 --- a/env/CONFIG +++ /dev/null @@ -1,5 +0,0 @@ -# "set"-syntax needed only for tcsh (but works with bash and zsh) -set OMP_NUM_THREADS = 4 - -set MSC_ROOT = /opt/msc -set MSC_VERSION = 2020 diff --git a/env/DAMASK.sh b/env/DAMASK.sh index f8ccfc1e0..edf019921 100644 --- a/env/DAMASK.sh +++ b/env/DAMASK.sh @@ -19,17 +19,9 @@ fi DAMASK_ROOT=$(canonicalPath "$ENV_ROOT/../") - # shorthand command to change to DAMASK_ROOT directory eval "function DAMASK_root() { cd $DAMASK_ROOT; }" -# defining set() allows to source the same file for tcsh and bash, with and without space around = -set() { - export $1$2$3 - } -source $ENV_ROOT/CONFIG -unset -f set - # add BRANCH if DAMASK_ROOT is a git repository cd $DAMASK_ROOT >/dev/null; BRANCH=$(git branch 2>/dev/null| grep -E '^\* '); cd - >/dev/null @@ -86,9 +78,6 @@ if [ ! -z "$PS1" ]; then echo fi -export OMP_NUM_THREADS -export MSC_ROOT -export MSC_VERSION export DAMASK_ROOT export PYTHONPATH=$DAMASK_ROOT/python:$PYTHONPATH diff --git a/env/DAMASK.zsh b/env/DAMASK.zsh index 2c74657fd..07064eb7a 100644 --- a/env/DAMASK.zsh +++ b/env/DAMASK.zsh @@ -12,16 +12,6 @@ function blink { ENV_ROOT=$(canonicalPath "${0:a:h}") DAMASK_ROOT=$(canonicalPath "${0:a:h}'/..") -# shorthand command to change to DAMASK_ROOT directory -eval "function DAMASK_root() { cd $DAMASK_ROOT; }" - -# defining set() allows to source the same file for tcsh and zsh, with and without space around = -set() { - export $1$2$3 - } -source $ENV_ROOT/CONFIG -unset -f set - # add BRANCH if DAMASK_ROOT is a git repository cd $DAMASK_ROOT >/dev/null; BRANCH=$(git branch 2>/dev/null| grep -E '^\* '); cd - >/dev/null @@ -80,9 +70,6 @@ if [ ! -z "$PS1" ]; then echo fi -export OMP_NUM_THREADS -export MSC_ROOT -export MSC_VERSION export DAMASK_ROOT export PYTHONPATH=$DAMASK_ROOT/python:$PYTHONPATH From 6699f2ee5f873532f3526869820f1aec6ed09851 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 22 Apr 2021 08:49:52 +0200 Subject: [PATCH 196/219] don't use shell variables Marc solver can be controlled in python, installation can be tuned with CLI arguments --- .gitlab-ci.yml | 2 +- .../mods_MarcMentat/2020/Mentat_bin/submit4 | 2 +- .../mods_MarcMentat/2020/Mentat_bin/submit5 | 2 +- .../mods_MarcMentat/2020/Mentat_bin/submit6 | 2 +- .../apply_DAMASK_modifications.py | 27 ++++++++++++++----- python/damask/solver/_marc.py | 18 +++++++------ 6 files changed, 34 insertions(+), 19 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3228d8db6..8c3a3b622 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -207,7 +207,7 @@ J2_plasticBehavior: stage: fortran script: - module load $IntelMarc $HDF5Marc $MSC - - J2_plasticBehavior/test.py + - MSC_VERSION=2020 J2_plasticBehavior/test.py except: - master - release diff --git a/installation/mods_MarcMentat/2020/Mentat_bin/submit4 b/installation/mods_MarcMentat/2020/Mentat_bin/submit4 index 55e3bcf03..09efd16bb 100644 --- a/installation/mods_MarcMentat/2020/Mentat_bin/submit4 +++ b/installation/mods_MarcMentat/2020/Mentat_bin/submit4 @@ -4,7 +4,7 @@ # Normal exit status is 0. # -DIR=%INSTALLDIR%/marc%VERSION% +DIR=%INSTALLDIR%/marc2020 if test $MARCDIR1 then diff --git a/installation/mods_MarcMentat/2020/Mentat_bin/submit5 b/installation/mods_MarcMentat/2020/Mentat_bin/submit5 index 8699cf076..d7cf96c68 100644 --- a/installation/mods_MarcMentat/2020/Mentat_bin/submit5 +++ b/installation/mods_MarcMentat/2020/Mentat_bin/submit5 @@ -4,7 +4,7 @@ # Normal exit status is 0. # -DIR=%INSTALLDIR%/marc%VERSION% +DIR=%INSTALLDIR%/marc2020 if test $MARCDIR1 then diff --git a/installation/mods_MarcMentat/2020/Mentat_bin/submit6 b/installation/mods_MarcMentat/2020/Mentat_bin/submit6 index a0179482f..f672ea667 100644 --- a/installation/mods_MarcMentat/2020/Mentat_bin/submit6 +++ b/installation/mods_MarcMentat/2020/Mentat_bin/submit6 @@ -4,7 +4,7 @@ # Normal exit status is 0. # -DIR=%INSTALLDIR%/marc%VERSION% +DIR=%INSTALLDIR%/marc2020 if test $MARCDIR1 then diff --git a/installation/mods_MarcMentat/apply_DAMASK_modifications.py b/installation/mods_MarcMentat/apply_DAMASK_modifications.py index 1cd93c47c..5b6b7a2ce 100755 --- a/installation/mods_MarcMentat/apply_DAMASK_modifications.py +++ b/installation/mods_MarcMentat/apply_DAMASK_modifications.py @@ -5,23 +5,36 @@ import glob import argparse from pathlib import Path -msc_version = os.environ['MSC_VERSION'] -msc_root = Path(os.environ['MSC_ROOT']) -damask_root = Path(os.environ['DAMASK_ROOT']) +import damask parser = argparse.ArgumentParser( - description='Apply DAMASK modification to MSC.Marc/Mentat', - epilog = f'MSC_ROOT={msc_root} and MSC_VERSION={msc_version} (from {damask_root}/env/CONFIG)') + description='Apply DAMASK modification to MSC.Marc/Mentat', + prog = Path(__file__).name, + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('--editor', dest='editor', metavar='string', default='vi', help='Name of the editor for MSC.Mentat (executable)') +parser.add_argument('--msc-root', dest='msc_root', metavar='string', + default=damask.solver._marc._msc_root, + help='MSC.Marc/Mentat root directory') +parser.add_argument('--msc-version', dest='msc_version', metavar='string', + default=damask.solver._marc._msc_version, + help='MSC.Marc/Mentat version') +parser.add_argument('--damask-root', dest='damask_root', type=float, metavar = 'float', + default=damask.solver._marc._damask_root, + help='DAMASK root directory') +args = parser.parse_args() +msc_root = Path(args.msc_root) +damask_root = Path(args.damask_root) +msc_version = args.msc_version + def copy_and_replace(in_file,dst): with open(in_file) as f: content = f.read() content = content.replace('%INSTALLDIR%',str(msc_root)) - content = content.replace('%VERSION%', msc_version) - content = content.replace('%EDITOR%', parser.parse_args().editor) + content = content.replace('%EDITOR%', args.editor) with open(dst/Path(in_file).name,'w') as f: f.write(content) diff --git a/python/damask/solver/_marc.py b/python/damask/solver/_marc.py index a6707efd9..b09394e67 100644 --- a/python/damask/solver/_marc.py +++ b/python/damask/solver/_marc.py @@ -1,16 +1,16 @@ import subprocess import shlex import re -import os from pathlib import Path -_default_version='2020' -_default_path='/opt/msc' +_msc_version = 2020 +_msc_root = '/opt/msc' +_damask_root = str(Path(__file__).parents[3]) class Marc: """Wrapper to run DAMASK with MSCMarc.""" - def __init__(self,version=os.environ.get('MSC_VERSION',_default_version)): + def __init__(self,msc_version=_msc_version,msc_root=_msc_root,damask_root=_damask_root): """ Create a Marc solver object. @@ -20,12 +20,14 @@ class Marc: Marc version """ - self.version = version + self.msc_version = msc_version + self.msc_root = Path(msc_root) + self.damask_root = Path(damask_root) @property def library_path(self): - path_lib = Path(f'{os.environ.get("MSC_ROOT",_default_path)}/mentat{self.version}/shlib/linux64') + path_lib = self.msc_root/f'mentat{self.msc_version}/shlib/linux64' if not path_lib.is_dir(): raise FileNotFoundError(f'library path "{path_lib}" not found') @@ -35,7 +37,7 @@ class Marc: @property def tools_path(self): - path_tools = Path(f'{os.environ.get("MSC_ROOT",_default_path)}/marc{self.version}/tools') + path_tools = self.msc_root/f'marc{self.msc_version}/tools' if not path_tools.is_dir(): raise FileNotFoundError(f'tools path "{path_tools}" not found') @@ -46,7 +48,7 @@ class Marc: compile = False, optimization = ''): - usersub = Path(os.environ['DAMASK_ROOT'])/'src/DAMASK_Marc' + usersub = self.damask_root/'src/DAMASK_Marc' usersub = usersub.parent/(usersub.name + ('.f90' if compile else '.marc')) if not usersub.is_file(): raise FileNotFoundError(f'subroutine ({"source" if compile else "binary"}) "{usersub}" not found') From 26f37d822d39702b1117785dd4c7d9dc69915a9e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 23 Apr 2021 19:15:11 +0200 Subject: [PATCH 197/219] state return value not for Rotation as its docstring is extended by Orientation --- python/damask/_colormap.py | 14 +++++- python/damask/_grid.py | 99 +++++++++++++++++++++++++++++++++++++- python/damask/_rotation.py | 40 ++++++++++++--- 3 files changed, 142 insertions(+), 11 deletions(-) diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index de63508b3..0d36c1ee6 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -91,6 +91,11 @@ class Colormap(mpl.colors.ListedColormap): - 'lab': CIE Lab. - 'msh': Msh (for perceptual uniform interpolation). + Returns + ------- + new : damask.Colormap + Colormap within given bounds. + """ low_high = np.vstack((low,high)) if model.lower() == 'rgb': @@ -150,6 +155,11 @@ class Colormap(mpl.colors.ListedColormap): This parameter is not used for matplotlib colormaps that are of type `ListedColormap`. + Returns + ------- + new : damask.Colormap + Predefined colormap. + """ # matplotlib presets try: @@ -239,8 +249,8 @@ class Colormap(mpl.colors.ListedColormap): Returns ------- - f - File handle + f : file object + File handle with write access. """ if fname is None: diff --git a/python/damask/_grid.py b/python/damask/_grid.py index 308be5c80..5f5bad63d 100644 --- a/python/damask/_grid.py +++ b/python/damask/_grid.py @@ -161,6 +161,11 @@ class Grid: Grid file to read. Valid extension is .vtr, which will be appended if not given. + Returns + ------- + loaded : damask.Grid + Geometry representation from file. + """ v = VTK.load(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr') comments = v.get_comments() @@ -190,6 +195,11 @@ class Grid: fname : str, pathlib.Path, or file handle Geometry file to read. + Returns + ------- + loaded : damask.Grid + Geometry representation from file. + """ warnings.warn('Support for ASCII-based geom format will be removed in DAMASK 3.1.0', DeprecationWarning,2) try: @@ -281,6 +291,10 @@ class Grid: and grain- or cell-wise data. Defaults to None, in which case it is set as the path that contains _SIMPL_GEOMETRY/SPACING. + Returns + ------- + loaded : damask.Grid + Geometry representation from file. """ b = util.DREAM3D_base_group(fname) if base_group is None else base_group @@ -319,6 +333,11 @@ class Grid: Label(s) of the columns containing the material definition. Each unique combination of values results in one material ID. + Returns + ------- + new : damask.Grid + Geometry representation from values in table. + """ cells,size,origin = grid_filters.cellsSizeOrigin_coordinates0_point(table.get(coordinates)) @@ -356,6 +375,11 @@ class Grid: periodic : Boolean, optional Assume grid to be periodic. Defaults to True. + Returns + ------- + new : damask.Grid + Geometry representation from tessellation. + """ if periodic: weights_p = np.tile(weights,27) # Laguerre weights (1,2,3,1,2,3,...,1,2,3) @@ -405,6 +429,11 @@ class Grid: periodic : Boolean, optional Assume grid to be periodic. Defaults to True. + Returns + ------- + new : damask.Grid + Geometry representation from tessellation. + """ coords = grid_filters.coordinates0_point(cells,size).reshape(-1,3) KDTree = spatial.cKDTree(seeds,boxsize=size) if periodic else spatial.cKDTree(seeds) @@ -478,6 +507,11 @@ class Grid: materials : (int, int), optional Material IDs. Defaults to (1,2). + Returns + ------- + new : damask.Grid + Geometry representation defined by a minimal surface. + Notes ----- The following triply-periodic minimal surfaces are implemented: @@ -598,6 +632,11 @@ class Grid: periodic : Boolean, optional Assume grid to be periodic. Defaults to True. + Returns + ------- + updated : damask.Grid + Updated geometry representation. + """ # radius and center r = np.array(dimension)/2.0*self.size/self.cells if np.array(dimension).dtype in np.sctypes['int'] else \ @@ -638,6 +677,11 @@ class Grid: reflect : bool, optional Reflect (include) outermost layers. Defaults to False. + Returns + ------- + updated : damask.Grid + Updated geometry representation. + """ valid = ['x','y','z'] if not set(directions).issubset(valid): @@ -670,6 +714,11 @@ class Grid: Direction(s) along which the grid is flipped. Valid entries are 'x', 'y', 'z'. + Returns + ------- + updated : damask.Grid + Updated geometry representation. + """ valid = ['x','y','z'] if not set(directions).issubset(valid): @@ -695,6 +744,11 @@ class Grid: periodic : Boolean, optional Assume grid to be periodic. Defaults to True. + Returns + ------- + updated : damask.Grid + Updated geometry representation. + """ return Grid(material = ndimage.interpolation.zoom( self.material, @@ -723,6 +777,11 @@ class Grid: periodic : Boolean, optional Assume grid to be periodic. Defaults to True. + Returns + ------- + updated : damask.Grid + Updated geometry representation. + """ def mostFrequent(arr,selection=None): me = arr[arr.size//2] @@ -746,7 +805,15 @@ class Grid: def renumber(self): - """Renumber sorted material indices as 0,...,N-1.""" + """ + Renumber sorted material indices as 0,...,N-1. + + Returns + ------- + updated : damask.Grid + Updated geometry representation. + + """ _,renumbered = np.unique(self.material,return_inverse=True) return Grid(material = renumbered.reshape(self.cells), @@ -767,6 +834,11 @@ class Grid: fill : int or float, optional Material index to fill the corners. Defaults to material.max() + 1. + Returns + ------- + updated : damask.Grid + Updated geometry representation. + """ if fill is None: fill = np.nanmax(self.material) + 1 dtype = float if isinstance(fill,float) or self.material.dtype in np.sctypes['float'] else int @@ -802,6 +874,11 @@ class Grid: fill : int or float, optional Material index to fill the background. Defaults to material.max() + 1. + Returns + ------- + updated : damask.Grid + Updated geometry representation. + """ if offset is None: offset = 0 if fill is None: fill = np.nanmax(self.material) + 1 @@ -834,6 +911,11 @@ class Grid: to_material : iterable of ints New material indices. + Returns + ------- + updated : damask.Grid + Updated geometry representation. + """ def mp(entry,mapper): return mapper[entry] if entry in mapper else entry @@ -849,7 +931,15 @@ class Grid: def sort(self): - """Sort material indices such that min(material) is located at (0,0,0).""" + """ + Sort material indices such that min(material) is located at (0,0,0). + + Returns + ------- + updated : damask.Grid + Updated geometry representation. + + """ a = self.material.flatten(order='F') from_ma = pd.unique(a) sort_idx = np.argsort(from_ma) @@ -884,6 +974,11 @@ class Grid: periodic : Boolean, optional Assume grid to be periodic. Defaults to True. + Returns + ------- + updated : damask.Grid + Updated geometry representation. + """ def tainted_neighborhood(stencil,trigger): diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index fff53fc73..47ac59eb3 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -357,7 +357,7 @@ class Rotation: Parameters ---------- - other : Rotation or list of Rotations. + other : damask.Rotation """ return self.copy(rotation=np.vstack(tuple(map(lambda x:x.quaternion, @@ -365,12 +365,28 @@ class Rotation: def flatten(self,order = 'C'): - """Flatten array.""" + """ + Flatten array. + + Returns + ------- + flattened : damask.Rotation + Rotation flattened to single dimension. + + """ return self.copy(rotation=self.quaternion.reshape((-1,4),order=order)) def reshape(self,shape,order = 'C'): - """Reshape array.""" + """ + Reshape array. + + Returns + ------- + reshaped : damask.Rotation + Rotation of given shape. + + """ if isinstance(shape,(int,np.integer)): shape = (shape,) return self.copy(rotation=self.quaternion.reshape(tuple(shape)+(4,),order=order)) @@ -387,6 +403,11 @@ class Rotation: Where to preferentially locate missing dimensions. Either 'left' or 'right' (default). + Returns + ------- + broadcasted : damask.Rotation + Rotation broadcasted to given shape. + """ if isinstance(shape,(int,np.integer)): shape = (shape,) return self.copy(rotation=np.broadcast_to(self.quaternion.reshape(util.shapeshifter(self.shape,shape,mode)+(4,)), @@ -404,7 +425,7 @@ class Rotation: Returns ------- - average : Rotation + average : damask.Rotation Weighted average of original Rotation field. References @@ -438,9 +459,14 @@ class Rotation: Parameters ---------- - other : Rotation + other : damask.Rotation Rotation to which the misorientation is computed. + Returns + ------- + g : damask.Rotation + Misorientation. + """ return other*~self @@ -531,10 +557,10 @@ class Rotation: Returns ------- - rho : numpy.ndarray of shape (...,4) containing + rho : numpy.ndarray of shape (...,4) containing [n_1, n_2, n_3, tan(ω/2)], ǀnǀ = 1 and ω ∈ [0,π] unless compact == True: - numpy.ndarray of shape (...,3) containing + numpy.ndarray of shape (...,3) containing tan(ω/2) [n_1, n_2, n_3], ω ∈ [0,π]. """ From 4d67c85a334cc47c12065d23199bfc7c22c3158a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 23 Apr 2021 19:20:07 +0200 Subject: [PATCH 198/219] clarify out-of-place behavior and document return values --- PRIVATE | 2 +- python/damask/_configmaterial.py | 132 ++++++++++-------- python/damask/_result.py | 30 +++- python/damask/_table.py | 36 +++-- python/damask/grid_filters.py | 223 +++++++++++++++++++++--------- python/damask/mechanics.py | 10 +- python/damask/seeds.py | 15 ++ python/tests/test_grid_filters.py | 18 ++- 8 files changed, 324 insertions(+), 142 deletions(-) diff --git a/PRIVATE b/PRIVATE index 23eac08c9..d58a002b0 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 23eac08c9f9638f8dae76710095222d00f948eec +Subproject commit d58a002b0a43d240f143aee1396fdc766d87a886 diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index 557907594..ad085e5c2 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -14,7 +14,7 @@ class ConfigMaterial(Config): A complete material configuration file has the entries 'material', 'phase', and 'homogenization'. For use in DAMASK, it needs to be stored as 'material.yaml'. - + """ def __init__(self,d=None): @@ -60,54 +60,6 @@ class ConfigMaterial(Config): return super(ConfigMaterial,cls).load(fname) - @staticmethod - def from_table(table,**kwargs): - """ - Generate from an ASCII table. - - Parameters - ---------- - table : damask.Table - Table that contains material information. - **kwargs - Keyword arguments where the key is the name and the value specifies - the label of the data column in the table. - - Examples - -------- - >>> import damask - >>> import damask.ConfigMaterial as cm - >>> t = damask.Table.load('small.txt') - >>> t - pos pos pos qu qu qu qu phase homog - 0 0 0 0 0.19 0.8 0.24 -0.51 Aluminum SX - 1 1 0 0 0.8 0.19 0.24 -0.51 Steel SX - 1 1 1 0 0.8 0.19 0.24 -0.51 Steel SX - >>> cm.from_table(t,O='qu',phase='phase',homogenization='homog') - material: - - constituents: - - O: [0.19, 0.8, 0.24, -0.51] - v: 1.0 - phase: Aluminum - homogenization: SX - - constituents: - - O: [0.8, 0.19, 0.24, -0.51] - v: 1.0 - phase: Steel - homogenization: SX - homogenization: {} - phase: {} - - """ - kwargs_ = {k:table.get(v) for k,v in kwargs.items()} - - _,idx = np.unique(np.hstack(list(kwargs_.values())),return_index=True,axis=0) - idx = np.sort(idx) - kwargs_ = {k:np.atleast_1d(v[idx].squeeze()) for k,v in kwargs_.items()} - - return ConfigMaterial().material_add(**kwargs_) - - @staticmethod def load_DREAM3D(fname, grain_data=None,cell_data=None,cell_ensemble_data='CellEnsembleData', @@ -181,9 +133,69 @@ class ConfigMaterial(Config): return base_config.material_add(**constituent,homogenization='direct') + @staticmethod + def from_table(table,**kwargs): + """ + Generate from an ASCII table. + + Parameters + ---------- + table : damask.Table + Table that contains material information. + **kwargs + Keyword arguments where the key is the name and the value specifies + the label of the data column in the table. + + Examples + -------- + >>> import damask + >>> import damask.ConfigMaterial as cm + >>> t = damask.Table.load('small.txt') + >>> t + pos pos pos qu qu qu qu phase homog + 0 0 0 0 0.19 0.8 0.24 -0.51 Aluminum SX + 1 1 0 0 0.8 0.19 0.24 -0.51 Steel SX + 1 1 1 0 0.8 0.19 0.24 -0.51 Steel SX + >>> cm.from_table(t,O='qu',phase='phase',homogenization='homog') + material: + - constituents: + - O: [0.19, 0.8, 0.24, -0.51] + v: 1.0 + phase: Aluminum + homogenization: SX + - constituents: + - O: [0.8, 0.19, 0.24, -0.51] + v: 1.0 + phase: Steel + homogenization: SX + homogenization: {} + phase: {} + + """ + kwargs_ = {k:table.get(v) for k,v in kwargs.items()} + + _,idx = np.unique(np.hstack(list(kwargs_.values())),return_index=True,axis=0) + idx = np.sort(idx) + kwargs_ = {k:np.atleast_1d(v[idx].squeeze()) for k,v in kwargs_.items()} + + return ConfigMaterial().material_add(**kwargs_) + + @property def is_complete(self): - """Check for completeness.""" + """ + Check for completeness. + + Only the general file layout is considered. + This check does not consider whether parameters for + a particular phase/homogenization model are missing. + + Returns + ------- + complete : bool + Whether the material.yaml definition is complete. + + """ ok = True for top_level in ['homogenization','phase','material']: ok &= top_level in self @@ -236,7 +248,19 @@ class ConfigMaterial(Config): @property def is_valid(self): - """Check for valid content.""" + """ + Check for valid content. + + Only the generic file content is considered. + This check does not consider whether parameters for a + particular phase/homogenization mode are out of bounds. + + Returns + ------- + valid : bool + Whether the material.yaml definition is valid. + + """ ok = True if 'phase' in self: @@ -282,7 +306,7 @@ class ConfigMaterial(Config): Returns ------- - cfg : damask.ConfigMaterial + updated : damask.ConfigMaterial Updated material configuration. """ @@ -311,7 +335,7 @@ class ConfigMaterial(Config): Returns ------- - cfg : damask.ConfigMaterial + updated : damask.ConfigMaterial Updated material configuration. """ @@ -336,7 +360,7 @@ class ConfigMaterial(Config): Returns ------- - cfg : damask.ConfigMaterial + updated : damask.ConfigMaterial Updated material configuration. Examples diff --git a/python/damask/_result.py b/python/damask/_result.py index 96e76374a..a7f211f20 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -57,11 +57,15 @@ def _empty_like(dataset,N_materialpoints,fill_float,fill_int): class Result: """ - Manipulate and read DADF5 files. + Add data to and export from DADF5 files. DADF5 (DAMASK HDF5) files contain DAMASK results. - The group/folder structure reflects the input data - in material.yaml. + Their group/folder structure reflects the input data in material.yaml. + + This class provides a custom view on the DADF5 file. + Upon initialization, all attributes are visible. + Derived quantities can be added to the file and existing data can be exported based on the current view. + """ def __init__(self,fname): @@ -274,6 +278,11 @@ class Result: Name of datasets; supports '?' and '*' wildcards. True is equivalent to '*', False is equivalent to []. + Returns + ------- + view : damask.Result + View with where selected attributes are visible. + """ return self._manage_view('set',what,datasets) @@ -290,6 +299,11 @@ class Result: Name of datasets; supports '?' and '*' wildcards. True is equivalent to '*', False is equivalent to []. + Returns + ------- + modified_view : damask.Result + View with more visible attributes. + """ return self._manage_view('add',what,datasets) @@ -306,6 +320,11 @@ class Result: Name of datasets; supports '?' and '*' wildcards. True is equivalent to '*', False is equivalent to []. + Returns + ------- + modified_view : damask.Result + View with less visible attributes. + """ return self._manage_view('del',what,datasets) @@ -372,7 +391,7 @@ class Result: @property def coordinates0_point(self): - """Return initial coordinates of the cell centers.""" + """Initial/undeformed cell center coordinates.""" if self.structured: return grid_filters.coordinates0_point(self.cells,self.size,self.origin).reshape(-1,3,order='F') else: @@ -381,7 +400,7 @@ class Result: @property def coordinates0_node(self): - """Return initial coordinates of the cell centers.""" + """Initial/undeformed nodal coordinates.""" if self.structured: return grid_filters.coordinates0_node(self.cells,self.size,self.origin).reshape(-1,3,order='F') else: @@ -390,6 +409,7 @@ class Result: @property def geometry0(self): + """Initial/undeformed geometry.""" if self.structured: return VTK.from_rectilinear_grid(self.cells,self.size,self.origin) else: diff --git a/python/damask/_table.py b/python/damask/_table.py index 01d8c9863..a068ec02a 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -223,6 +223,11 @@ class Table: fname : file, str, or pathlib.Path Filename or file for reading. + Returns + ------- + loaded : damask.Table + Table data from file. + """ try: f = open(fname) @@ -275,6 +280,11 @@ class Table: fname : file, str, or pathlib.Path Filename or file for reading. + Returns + ------- + loaded : damask.Table + Table data from file. + """ try: f = open(fname) @@ -334,14 +344,14 @@ class Table: ---------- label : str Column label. - data : np.ndarray + data : numpy.ndarray New data. info : str, optional Human-readable information about the new data. Returns ------- - table : Table + updated : damask.Table Updated table. """ @@ -367,14 +377,14 @@ class Table: ---------- label : str Column label. - data : np.ndarray + data : numpy.ndarray Modified data. info : str, optional Human-readable information about the modified data. Returns ------- - table : Table + udated : damask.Table Updated table. """ @@ -402,7 +412,7 @@ class Table: Returns ------- - table : Table + udated : damask.Table Updated table. """ @@ -425,7 +435,7 @@ class Table: Returns ------- - table : Table + udated : damask.Table Updated table. """ @@ -451,7 +461,7 @@ class Table: Returns ------- - table : Table + udated : damask.Table Updated table. """ @@ -479,13 +489,13 @@ class Table: Parameters ---------- - other : Table + other : damask.Table Table to append. Returns ------- - table : Table - Concatenated table. + udated : damask.Table + Updated table. """ if self.shapes != other.shapes or not self.data.columns.equals(other.data.columns): @@ -504,13 +514,13 @@ class Table: Parameters ---------- - other : Table + other : damask.Table Table to join. Returns ------- - table : Table - Joined table. + udated : damask.Table + Updated table. """ if set(self.shapes) & set(other.shapes) or self.data.shape[0] != other.data.shape[0]: diff --git a/python/damask/grid_filters.py b/python/damask/grid_filters.py index ee929b3bf..d82f25ea9 100644 --- a/python/damask/grid_filters.py +++ b/python/damask/grid_filters.py @@ -5,11 +5,12 @@ Notes ----- The grids are defined as (x,y,z,...) where x is fastest and z is slowest. This convention is consistent with the layout in grid vtr files. + When converting to/from a plain list (e.g. storage in ASCII table), the following operations are required for tensorial data: -D3 = D1.reshape(cells+(-1,),order='F').reshape(cells+(3,3)) -D1 = D3.reshape(cells+(-1,)).reshape(-1,9,order='F') + - D3 = D1.reshape(cells+(-1,),order='F').reshape(cells+(3,3)) + - D1 = D3.reshape(cells+(-1,)).reshape(-1,9,order='F') """ from scipy import spatial as _spatial @@ -29,10 +30,12 @@ def _ks(size,cells,first_order=False): Correction for first order derivatives, defaults to False. """ - k_sk = _np.where(_np.arange(cells[0])>cells[0]//2,_np.arange(cells[0])-cells[0],_np.arange(cells[0]))/size[0] + k_sk = _np.where(_np.arange(cells[0])>cells[0]//2, + _np.arange(cells[0])-cells[0],_np.arange(cells[0]))/size[0] if cells[0]%2 == 0 and first_order: k_sk[cells[0]//2] = 0 # Nyquist freq=0 for even cells (Johnson, MIT, 2011) - k_sj = _np.where(_np.arange(cells[1])>cells[1]//2,_np.arange(cells[1])-cells[1],_np.arange(cells[1]))/size[1] + k_sj = _np.where(_np.arange(cells[1])>cells[1]//2, + _np.arange(cells[1])-cells[1],_np.arange(cells[1]))/size[1] if cells[1]%2 == 0 and first_order: k_sj[cells[1]//2] = 0 # Nyquist freq=0 for even cells (Johnson, MIT, 2011) k_si = _np.arange(cells[2]//2+1)/size[2] @@ -40,74 +43,89 @@ def _ks(size,cells,first_order=False): return _np.stack(_np.meshgrid(k_sk,k_sj,k_si,indexing = 'ij'), axis=-1) -def curl(size,field): - """ +def curl(size,f): + u""" Calculate curl of a vector or tensor field in Fourier space. Parameters ---------- size : numpy.ndarray of shape (3) Physical size of the periodic field. - field : numpy.ndarray of shape (:,:,:,3) or (:,:,:,3,3) + f : numpy.ndarray of shape (:,:,:,3) or (:,:,:,3,3) Periodic field of which the curl is calculated. + Returns + ------- + ∇ × f : numpy.ndarray + Curl of f. + """ - n = _np.prod(field.shape[3:]) - k_s = _ks(size,field.shape[:3],True) + n = _np.prod(f.shape[3:]) + k_s = _ks(size,f.shape[:3],True) e = _np.zeros((3, 3, 3)) e[0, 1, 2] = e[1, 2, 0] = e[2, 0, 1] = +1.0 # Levi-Civita symbol e[0, 2, 1] = e[2, 1, 0] = e[1, 0, 2] = -1.0 - field_fourier = _np.fft.rfftn(field,axes=(0,1,2)) - curl_ = (_np.einsum('slm,ijkl,ijkm ->ijks', e,k_s,field_fourier)*2.0j*_np.pi if n == 3 else # vector, 3 -> 3 - _np.einsum('slm,ijkl,ijknm->ijksn',e,k_s,field_fourier)*2.0j*_np.pi) # tensor, 3x3 -> 3x3 + f_fourier = _np.fft.rfftn(f,axes=(0,1,2)) + curl_ = (_np.einsum('slm,ijkl,ijkm ->ijks', e,k_s,f_fourier)*2.0j*_np.pi if n == 3 else # vector, 3 -> 3 + _np.einsum('slm,ijkl,ijknm->ijksn',e,k_s,f_fourier)*2.0j*_np.pi) # tensor, 3x3 -> 3x3 - return _np.fft.irfftn(curl_,axes=(0,1,2),s=field.shape[:3]) + return _np.fft.irfftn(curl_,axes=(0,1,2),s=f.shape[:3]) -def divergence(size,field): - """ +def divergence(size,f): + u""" Calculate divergence of a vector or tensor field in Fourier space. Parameters ---------- size : numpy.ndarray of shape (3) Physical size of the periodic field. - field : numpy.ndarray of shape (:,:,:,3) or (:,:,:,3,3) + f : numpy.ndarray of shape (:,:,:,3) or (:,:,:,3,3) Periodic field of which the divergence is calculated. + Returns + ------- + ∇ · f : numpy.ndarray + Divergence of f. + """ - n = _np.prod(field.shape[3:]) - k_s = _ks(size,field.shape[:3],True) + n = _np.prod(f.shape[3:]) + k_s = _ks(size,f.shape[:3],True) - field_fourier = _np.fft.rfftn(field,axes=(0,1,2)) - div_ = (_np.einsum('ijkl,ijkl ->ijk', k_s,field_fourier)*2.0j*_np.pi if n == 3 else # vector, 3 -> 1 - _np.einsum('ijkm,ijklm->ijkl',k_s,field_fourier)*2.0j*_np.pi) # tensor, 3x3 -> 3 + f_fourier = _np.fft.rfftn(f,axes=(0,1,2)) + div_ = (_np.einsum('ijkl,ijkl ->ijk', k_s,f_fourier)*2.0j*_np.pi if n == 3 else # vector, 3 -> 1 + _np.einsum('ijkm,ijklm->ijkl',k_s,f_fourier)*2.0j*_np.pi) # tensor, 3x3 -> 3 - return _np.fft.irfftn(div_,axes=(0,1,2),s=field.shape[:3]) + return _np.fft.irfftn(div_,axes=(0,1,2),s=f.shape[:3]) -def gradient(size,field): - """ - Calculate gradient of a scalar or vector field in Fourier space. +def gradient(size,f): + u""" + Calculate gradient of a scalar or vector fieldin Fourier space. Parameters ---------- size : numpy.ndarray of shape (3) Physical size of the periodic field. - field : numpy.ndarray of shape (:,:,:,1) or (:,:,:,3) + f : numpy.ndarray of shape (:,:,:,1) or (:,:,:,3) Periodic field of which the gradient is calculated. + Returns + ------- + ∇ f : numpy.ndarray + Divergence of f. + """ - n = _np.prod(field.shape[3:]) - k_s = _ks(size,field.shape[:3],True) + n = _np.prod(f.shape[3:]) + k_s = _ks(size,f.shape[:3],True) - field_fourier = _np.fft.rfftn(field,axes=(0,1,2)) - grad_ = (_np.einsum('ijkl,ijkm->ijkm', field_fourier,k_s)*2.0j*_np.pi if n == 1 else # scalar, 1 -> 3 - _np.einsum('ijkl,ijkm->ijklm',field_fourier,k_s)*2.0j*_np.pi) # vector, 3 -> 3x3 + f_fourier = _np.fft.rfftn(f,axes=(0,1,2)) + grad_ = (_np.einsum('ijkl,ijkm->ijkm', f_fourier,k_s)*2.0j*_np.pi if n == 1 else # scalar, 1 -> 3 + _np.einsum('ijkl,ijkm->ijklm',f_fourier,k_s)*2.0j*_np.pi) # vector, 3 -> 3x3 - return _np.fft.irfftn(grad_,axes=(0,1,2),s=field.shape[:3]) + return _np.fft.irfftn(grad_,axes=(0,1,2),s=f.shape[:3]) def coordinates0_point(cells,size,origin=_np.zeros(3)): @@ -123,6 +141,11 @@ def coordinates0_point(cells,size,origin=_np.zeros(3)): origin : numpy.ndarray, optional Physical origin of the periodic field. Defaults to [0.0,0.0,0.0]. + Returns + ------- + x_p_0 : numpy.ndarray + Undeformed cell center coordinates. + """ start = origin + size/cells*.5 end = origin + size - size/cells*.5 @@ -144,6 +167,11 @@ def displacement_fluct_point(size,F): F : numpy.ndarray Deformation gradient field. + Returns + ------- + u_p_fluct : numpy.ndarray + Fluctuating part of the cell center displacements. + """ integrator = 0.5j*size/_np.pi @@ -171,6 +199,11 @@ def displacement_avg_point(size,F): F : numpy.ndarray Deformation gradient field. + Returns + ------- + u_p_avg : numpy.ndarray + Average part of the cell center displacements. + """ F_avg = _np.average(F,axis=(0,1,2)) return _np.einsum('ml,ijkl->ijkm',F_avg - _np.eye(3),coordinates0_point(F.shape[:3],size)) @@ -187,6 +220,11 @@ def displacement_point(size,F): F : numpy.ndarray Deformation gradient field. + Returns + ------- + u_p : numpy.ndarray + Cell center displacements. + """ return displacement_avg_point(size,F) + displacement_fluct_point(size,F) @@ -204,6 +242,11 @@ def coordinates_point(size,F,origin=_np.zeros(3)): origin : numpy.ndarray of shape (3), optional Physical origin of the periodic field. Defaults to [0.0,0.0,0.0]. + Returns + ------- + x_p : numpy.ndarray + Cell center coordinates. + """ return coordinates0_point(F.shape[:3],size,origin) + displacement_point(size,F) @@ -252,19 +295,6 @@ def cellsSizeOrigin_coordinates0_point(coordinates0,ordered=True): return (cells,size,origin) -def coordinates0_check(coordinates0): - """ - Check whether coordinates lie on a regular grid. - - Parameters - ---------- - coordinates0 : numpy.ndarray - Array of undeformed cell coordinates. - - """ - cellsSizeOrigin_coordinates0_point(coordinates0,ordered=True) - - def coordinates0_node(cells,size,origin=_np.zeros(3)): """ Nodal positions (undeformed). @@ -278,6 +308,11 @@ def coordinates0_node(cells,size,origin=_np.zeros(3)): origin : numpy.ndarray of shape (3), optional Physical origin of the periodic field. Defaults to [0.0,0.0,0.0]. + Returns + ------- + x_n_0 : numpy.ndarray + Undeformed nodal coordinates. + """ return _np.stack(_np.meshgrid(_np.linspace(origin[0],size[0]+origin[0],cells[0]+1), _np.linspace(origin[1],size[1]+origin[1],cells[1]+1), @@ -296,6 +331,11 @@ def displacement_fluct_node(size,F): F : numpy.ndarray Deformation gradient field. + Returns + ------- + u_n_fluct : numpy.ndarray + Fluctuating part of the nodal displacements. + """ return point_to_node(displacement_fluct_point(size,F)) @@ -311,6 +351,11 @@ def displacement_avg_node(size,F): F : numpy.ndarray Deformation gradient field. + Returns + ------- + u_n_avg : numpy.ndarray + Average part of the nodal displacements. + """ F_avg = _np.average(F,axis=(0,1,2)) return _np.einsum('ml,ijkl->ijkm',F_avg - _np.eye(3),coordinates0_node(F.shape[:3],size)) @@ -327,6 +372,11 @@ def displacement_node(size,F): F : numpy.ndarray Deformation gradient field. + Returns + ------- + u_p : numpy.ndarray + Nodal displacements. + """ return displacement_avg_node(size,F) + displacement_fluct_node(size,F) @@ -344,28 +394,15 @@ def coordinates_node(size,F,origin=_np.zeros(3)): origin : numpy.ndarray of shape (3), optional Physical origin of the periodic field. Defaults to [0.0,0.0,0.0]. + Returns + ------- + x_n : numpy.ndarray + Nodal coordinates. + """ return coordinates0_node(F.shape[:3],size,origin) + displacement_node(size,F) -def point_to_node(cell_data): - """Interpolate periodic point data to nodal data.""" - n = ( cell_data + _np.roll(cell_data,1,(0,1,2)) - + _np.roll(cell_data,1,(0,)) + _np.roll(cell_data,1,(1,)) + _np.roll(cell_data,1,(2,)) - + _np.roll(cell_data,1,(0,1)) + _np.roll(cell_data,1,(1,2)) + _np.roll(cell_data,1,(2,0)))*0.125 - - return _np.pad(n,((0,1),(0,1),(0,1))+((0,0),)*len(cell_data.shape[3:]),mode='wrap') - - -def node_2_point(node_data): - """Interpolate periodic nodal data to point data.""" - c = ( node_data + _np.roll(node_data,1,(0,1,2)) - + _np.roll(node_data,1,(0,)) + _np.roll(node_data,1,(1,)) + _np.roll(node_data,1,(2,)) - + _np.roll(node_data,1,(0,1)) + _np.roll(node_data,1,(1,2)) + _np.roll(node_data,1,(2,0)))*0.125 - - return c[1:,1:,1:] - - def cellsSizeOrigin_coordinates0_node(coordinates0,ordered=True): """ Return grid 'DNA', i.e. cells, size, and origin from 1D array of nodal positions. @@ -402,6 +439,66 @@ def cellsSizeOrigin_coordinates0_node(coordinates0,ordered=True): return (cells,size,origin) +def point_to_node(cell_data): + """ + Interpolate periodic point data to nodal data. + + Parameters + ---------- + cell_data : numpy.ndarray of shape (:,:,:,...) + Data defined on the cell centers of a periodic grid. + + Returns + ------- + node_data : numpy.ndarray of shape (:,:,:,...) + Data defined on the nodes of a periodic grid. + """ + n = ( cell_data + _np.roll(cell_data,1,(0,1,2)) + + _np.roll(cell_data,1,(0,)) + _np.roll(cell_data,1,(1,)) + _np.roll(cell_data,1,(2,)) + + _np.roll(cell_data,1,(0,1)) + _np.roll(cell_data,1,(1,2)) + _np.roll(cell_data,1,(2,0)))*0.125 + + return _np.pad(n,((0,1),(0,1),(0,1))+((0,0),)*len(cell_data.shape[3:]),mode='wrap') + + +def node_to_point(node_data): + """ + Interpolate periodic nodal data to point data. + + Parameters + ---------- + node_data : numpy.ndarray of shape (:,:,:,...) + Data defined on the nodes of a periodic grid. + + Returns + ------- + cell_data : numpy.ndarray of shape (:,:,:,...) + Data defined on the cell centers of a periodic grid. + + """ + c = ( node_data + _np.roll(node_data,1,(0,1,2)) + + _np.roll(node_data,1,(0,)) + _np.roll(node_data,1,(1,)) + _np.roll(node_data,1,(2,)) + + _np.roll(node_data,1,(0,1)) + _np.roll(node_data,1,(1,2)) + _np.roll(node_data,1,(2,0)))*0.125 + + return c[1:,1:,1:] + + +def coordinates0_valid(coordinates0): + """ + Check whether coordinates lie on a regular grid. + + Parameters + ---------- + coordinates0 : numpy.ndarray + Array of undeformed cell coordinates. + + """ + try: + cellsSizeOrigin_coordinates0_point(coordinates0,ordered=True) + return True + except ValueError: + return False + + def regrid(size,F,cells): """ Return mapping from coordinates in deformed configuration to a regular grid. diff --git a/python/damask/mechanics.py b/python/damask/mechanics.py index 66f5c9916..8512023fc 100644 --- a/python/damask/mechanics.py +++ b/python/damask/mechanics.py @@ -1,4 +1,11 @@ -"""Finite-strain continuum mechanics.""" +""" +Finite-strain continuum mechanics. + +Notes +----- +Collection of routines to operate on numpy.ndarrays of shape (...,3,3). + +""" from . import tensor as _tensor from . import _rotation @@ -154,7 +161,6 @@ def strain(F,t,m): return eps - def stress_Cauchy(P,F): """ Calculate the Cauchy stress (true stress). diff --git a/python/damask/seeds.py b/python/damask/seeds.py index 9ab148a82..74d15f1ef 100644 --- a/python/damask/seeds.py +++ b/python/damask/seeds.py @@ -24,6 +24,11 @@ def from_random(size,N_seeds,cells=None,rng_seed=None): A seed to initialize the BitGenerator. Defaults to None. If None, then fresh, unpredictable entropy will be pulled from the OS. + Returns + ------- + new : numpy.ndarray of shape (N_seeds,3) + Coordinates in 3D space. + """ rng = _np.random.default_rng(rng_seed) if cells is None: @@ -56,6 +61,11 @@ def from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=True,rng_seed= A seed to initialize the BitGenerator. Defaults to None. If None, then fresh, unpredictable entropy will be pulled from the OS. + Returns + ------- + new : numpy.ndarray of shape (N_seeds,3) + Coordinates in 3D space. + """ rng = _np.random.default_rng(rng_seed) coords = _np.empty((N_seeds,3)) @@ -94,6 +104,11 @@ def from_grid(grid,selection=None,invert=False,average=False,periodic=True): periodic : boolean, optional Center of gravity with periodic boundaries. + Returns + ------- + new : numpy.ndarray of shape (...,3) + Coordinates in 3D space. + """ material = grid.material.reshape((-1,1),order='F') mask = _np.full(grid.cells.prod(),True,dtype=bool) if selection is None else \ diff --git a/python/tests/test_grid_filters.py b/python/tests/test_grid_filters.py index d43e94c3c..d9c074c11 100644 --- a/python/tests/test_grid_filters.py +++ b/python/tests/test_grid_filters.py @@ -60,7 +60,7 @@ class TestGridFilters: cell_field_x = np.interp(coordinates0_point_x,coordinates_node_x,node_field_x,period=np.pi*2.) cell_field = np.broadcast_to(cell_field_x.reshape(-1,1,1),cells) - assert np.allclose(cell_field,grid_filters.node_2_point(node_field)) + assert np.allclose(cell_field,grid_filters.node_to_point(node_field)) @pytest.mark.parametrize('mode',['point','node']) def test_coordinates0_origin(self,mode): @@ -93,14 +93,24 @@ class TestGridFilters: F = np.broadcast_to(np.random.random((3,3)), tuple(cells)+(3,3)) assert np.allclose(function(size,F),0.0) - @pytest.mark.parametrize('function',[grid_filters.coordinates0_check, - grid_filters.cellsSizeOrigin_coordinates0_node, - grid_filters.cellsSizeOrigin_coordinates0_point]) + @pytest.mark.parametrize('function',[grid_filters.cellsSizeOrigin_coordinates0_point, + grid_filters.cellsSizeOrigin_coordinates0_node]) def test_invalid_coordinates(self,function): invalid_coordinates = np.random.random((np.random.randint(12,52),3)) with pytest.raises(ValueError): function(invalid_coordinates) + @pytest.mark.parametrize('function',[grid_filters.coordinates0_point, + grid_filters.coordinates0_node]) + def test_valid_coordinates_check(self,function): + valid_coordinates = function(np.random.randint(4,10,(3)),np.random.rand(3)) + assert grid_filters.coordinates0_valid(valid_coordinates.reshape(-1,3,order='F')) + + def test_invalid_coordinates_check(self): + invalid_coordinates = np.random.random((np.random.randint(12,52),3)) + assert not grid_filters.coordinates0_valid(invalid_coordinates) + + @pytest.mark.parametrize('function',[grid_filters.cellsSizeOrigin_coordinates0_node, grid_filters.cellsSizeOrigin_coordinates0_point]) def test_uneven_spaced_coordinates(self,function): From 3977e230b36849acbafb12c4667756da75254245 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 24 Apr 2021 07:13:36 +0200 Subject: [PATCH 199/219] documenting and ensuring consistent argument names 'name' for a dataset matches the analogy to a file name --- .../plastic/dislotwin_IF-steel.yaml | 1 + python/damask/_configmaterial.py | 34 +- python/damask/_orientation.py | 12 +- python/damask/_result.py | 332 +++++++++++++++--- python/damask/_table.py | 6 +- python/damask/_vtk.py | 10 +- python/damask/mechanics.py | 2 +- python/tests/test_Result.py | 20 +- 8 files changed, 329 insertions(+), 88 deletions(-) diff --git a/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml b/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml index 9d0c5be8b..bebe0f341 100644 --- a/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml +++ b/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml @@ -5,6 +5,7 @@ references: 10.1016/j.ijplas.2020.102779 - K. Sedighiani et al., Mechanics of Materials, submitted +output: [rho_dip, rho_mob] N_sl: [12, 12] b_sl: [2.49e-10, 2.49e-10] rho_mob_0: [2.81e12, 2.8e12] diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index ad085e5c2..e927874f3 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -365,48 +365,56 @@ class ConfigMaterial(Config): Examples -------- + Create a dual-phase steel microstructure for micromechanical simulations: + >>> import numpy as np >>> import damask - >>> m = damask.ConfigMaterial().material_add(phase = ['Aluminum','Steel'], - ... O = damask.Rotation.from_random(2), - ... homogenization = 'SX') + >>> m = damask.ConfigMaterial() + >>> m = m.material_add(phase = ['Ferrite','Martensite'], + ... O = damask.Rotation.from_random(2), + ... homogenization = 'SX') >>> m material: - constituents: - O: [0.577764, -0.146299, -0.617669, 0.513010] v: 1.0 - phase: Aluminum + phase: Ferrite homogenization: SX - constituents: - O: [0.184176, 0.340305, 0.737247, 0.553840] v: 1.0 - phase: Steel + phase: Martensite homogenization: SX homogenization: {} phase: {} - >>> m = damask.ConfigMaterial().material_add(phase = np.array(['Austenite','Martensite']).reshape(1,2), - ... O = damask.Rotation.from_random((2,2)), - ... v = np.array([0.2,0.8]).reshape(1,2), - ... homogenization = ['A','B']) + Create a duplex stainless steel microstructure for forming simulations: + + >>> import numpy as np + >>> import damask + >>> m = damask.ConfigMaterial() + >>> m = m.material_add(phase = np.array(['Austenite','Ferrite']).reshape(1,2), + ... O = damask.Rotation.from_random((2,2)), + ... v = np.array([0.2,0.8]).reshape(1,2), + ... homogenization = 'Taylor') >>> m material: - constituents: - phase: Austenite O: [0.659802978293224, 0.6953785848195171, 0.22426295326327111, -0.17554139512785227] v: 0.2 - - phase: Martensite + - phase: Ferrite O: [0.49356745891301596, 0.2841806579193434, -0.7487679215072818, -0.339085707289975] v: 0.8 - homogenization: A + homogenization: Taylor - constituents: - phase: Austenite O: [0.26542221365204055, 0.7268854930702071, 0.4474726435701472, -0.44828201137283735] v: 0.2 - - phase: Martensite + - phase: Ferrite O: [0.6545817158479885, -0.08004812803625233, -0.6226561293931374, 0.4212059104577611] v: 0.8 - homogenization: B + homogenization: Taylor homogenization: {} phase: {} diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 5cc412c98..00e74d36c 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -8,15 +8,15 @@ from . import tensor _parameter_doc = \ """lattice : str - Either a crystal family out of [triclinic, monoclinic, orthorhombic, tetragonal, hexagonal, cubic] - or a Bravais lattice out of [aP, mP, mS, oP, oS, oI, oF, tP, tI, hP, cP, cI, cF]. - When specifying a Bravais lattice, additional lattice parameters might be required: + Either a crystal family out of {triclinic, monoclinic, orthorhombic, tetragonal, hexagonal, cubic} + or a Bravais lattice out of {aP, mP, mS, oP, oS, oI, oF, tP, tI, hP, cP, cI, cF}. + When specifying a Bravais lattice, additional lattice parameters might be required. a : float, optional - Length of lattice parameter "a". + Length of lattice parameter 'a'. b : float, optional - Length of lattice parameter "b". + Length of lattice parameter 'b'. c : float, optional - Length of lattice parameter "c". + Length of lattice parameter 'c'. alpha : float, optional Angle between b and c lattice basis. beta : float, optional diff --git a/python/damask/_result.py b/python/damask/_result.py index a7f211f20..62ee2d8fe 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -34,7 +34,7 @@ def _read(dataset): return np.array(dataset,dtype=dtype) def _match(requested,existing): - """Find matches among two sets of labels.""" + """Find matches among two sets of names.""" def flatten_list(list_of_lists): return [e for e_ in list_of_lists for e in e_] @@ -57,14 +57,29 @@ def _empty_like(dataset,N_materialpoints,fill_float,fill_int): class Result: """ - Add data to and export from DADF5 files. + Add data to and export data from a DADF5 file. - DADF5 (DAMASK HDF5) files contain DAMASK results. - Their group/folder structure reflects the input data in material.yaml. + A DADF5 (DAMASK HDF5) file contain DAMASK results. + Its group/folder structure reflects the layout in material.yaml. - This class provides a custom view on the DADF5 file. + This class provides a customable view on the DADF5 file. Upon initialization, all attributes are visible. - Derived quantities can be added to the file and existing data can be exported based on the current view. + Derived quantities are added to the file and existing data is + exported based on the current view. + + Examples + -------- + Open 'my_file.hdf5', which needs to contain deformation gradient 'F' + and first Piola-Kirchhoff stress 'P', add the Mises equivalent of the + Cauchy stress, and export it to VTK (file) and numpy.ndarray (memory). + + >>> import damask + >>> r = damask.Result('my_file.hdf5') + >>> r.add_Cauchy() + >>> r.add_equivalent_Mises('sigma') + >>> r.save_VTK() + >>> r_last = r.view('increments',-1) + >>> sigma_vM_last = r_last.get('sigma_vM') """ @@ -167,6 +182,11 @@ class Result: Name of datasets; supports '?' and '*' wildcards. True is equivalent to '*', False is equivalent to []. + Returns + ------- + view : damask.Result + Modified or new view on the DADF5 file. + """ # allow True/False and string arguments if datasets is True: @@ -180,6 +200,7 @@ class Result: if what == 'increments': choice = [c if isinstance(c,str) and c.startswith(inc) else f'{inc}{c}' for c in choice] + if datasets == -1: choice = [self.increments[-1]] elif what == 'times': what = 'increments' if choice == ['*']: @@ -211,15 +232,31 @@ class Result: return dup - def allow_modification(self): - """Allow to overwrite existing data.""" + def modification_enable(self): + """ + Allow to modify existing data. + + Returns + ------- + modified_view : damask.Result + View where data is not write-protected. + + """ print(util.warn('Warning: Modification of existing datasets allowed!')) dup = self.copy() dup._allow_modification = True return dup - def disallow_modification(self): - """Disallow to overwrite existing data (default case).""" + def modification_disable(self): + """ + Disallow to modify existing data (default case). + + Returns + ------- + modified_view : damask.Result + View where data is write-protected. + + """ dup = self.copy() dup._allow_modification = False return dup @@ -227,7 +264,7 @@ class Result: def increments_in_range(self,start,end): """ - Select all increments within a given range. + Get all increments within a given range. Parameters ---------- @@ -236,6 +273,10 @@ class Result: end : int or str End increment. + Returns + ------- + increments : list of ints + Increment number of all increments within the given bounds. """ # compatibility hack ln = 3 if self.version_minor < 12 else 10 @@ -243,13 +284,13 @@ class Result: for i,inc in enumerate([int(i[ln:]) for i in self.increments]): s,e = map(lambda x: int(x[ln:] if isinstance(x,str) and x.startswith('inc') else x), (start,end)) if s <= inc <= e: - selected.append(self.increments[i]) + selected.append(int(self.increments[i].split('_')[1])) return selected def times_in_range(self,start,end): """ - Select all increments within a given time range. + Get all increments within a given time range. Parameters ---------- @@ -258,6 +299,10 @@ class Result: end : float Time of end increment. + Returns + ------- + times : list of float + Simulation time of all increments within the given bounds. """ selected = [] for i,time in enumerate(self.times): @@ -283,6 +328,20 @@ class Result: view : damask.Result View with where selected attributes are visible. + Examples + -------- + Get a view that shows only results from the initial configuration: + + >>> import damask + >>> r = damask.Result('my_file.hdf5') + >>> r_first = r.view('increment',0) + + Get a view that shows all results of in simulation time [10,40]: + + >>> import damask + >>> r = damask.Result('my_file.hdf5') + >>> r_t10to40 = r.view('times',r.times_in_range(10.0,40.0)) + """ return self._manage_view('set',what,datasets) @@ -304,6 +363,15 @@ class Result: modified_view : damask.Result View with more visible attributes. + Examples + -------- + Get a view that shows only results from first and last increment: + + >>> import damask + >>> r_empty = damask.Result('my_file.hdf5').view('increments',False) + >>> r_first = r_empty.view_more('increments',0) + >>> r_first_and_last = r.first.view_more('increments',-1) + """ return self._manage_view('add',what,datasets) @@ -325,37 +393,93 @@ class Result: modified_view : damask.Result View with less visible attributes. + Examples + -------- + Get a view that does not show the undeformed configuration: + + >>> import damask + >>> r_all = damask.Result('my_file.hdf5') + >>> r_deformed = r_all.view_less('increments',0) + """ return self._manage_view('del',what,datasets) - def rename(self,name_old,name_new): + def rename(self,name_src,name_dst): """ - Rename dataset. + Rename/move datasets (within the same group/folder). + + This operation is discouraged because the history of the + data becomes untracable and scientific integrity cannot be + ensured. Parameters ---------- - name_old : str - Name of the dataset to be renamed. - name_new : str - New name of the dataset. + name_src : str + Name of the datasets to be renamed. + name_dst : str + New name of the datasets. + + Examples + -------- + Rename datasets containing the deformation gradient from 'F' to 'def_grad': + + >>> import damask + >>> r = damask.Result('my_file.hdf5') + >>> r_unprotected = r.modification_enable() + >>> r_unprotected.rename('F','def_grad') """ if not self._allow_modification: - raise PermissionError('Rename operation not permitted') + raise PermissionError('Renaming datasets not permitted') with h5py.File(self.fname,'a') as f: for inc in self.visible['increments']: for ty in ['phase','homogenization']: for label in self.visible[ty+'s']: for field in _match(self.visible['fields'],f['/'.join([inc,ty,label])].keys()): - path_old = '/'.join([inc,ty,label,field,name_old]) - path_new = '/'.join([inc,ty,label,field,name_new]) - if path_old in f.keys(): - f[path_new] = f[path_old] - f[path_new].attrs['renamed'] = f'original name: {name_old}' if h5py3 else \ - f'original name: {name_old}'.encode() - del f[path_old] + path_src = '/'.join([inc,ty,label,field,name_src]) + path_dst = '/'.join([inc,ty,label,field,name_dst]) + if path_src in f.keys(): + f[path_dst] = f[path_src] + f[path_dst].attrs['renamed'] = f'original name: {name_src}' if h5py3 else \ + f'original name: {name_src}'.encode() + del f[path_src] + + + def remove(self,name): + """ + Remove/delete datasets. + + This operation is discouraged because the history of the + data becomes untracable and scientific integrity cannot be + ensured. + + Parameters + ---------- + name : str + Name of the datasets to be deleted. + + Examples + -------- + Delete the deformation gradient 'F': + + >>> import damask + >>> r = damask.Result('my_file.hdf5') + >>> r_unprotected = r.modification_enable() + >>> r_unprotected.remove('F') + + """ + if not self._allow_modification: + raise PermissionError('Removing datasets not permitted') + + with h5py.File(self.fname,'a') as f: + for inc in self.visible['increments']: + for ty in ['phase','homogenization']: + for label in self.visible[ty+'s']: + for field in _match(self.visible['fields'],f['/'.join([inc,ty,label])].keys()): + path = '/'.join([inc,ty,label,field,name]) + if path in f.keys(): del f[path] def list_data(self): @@ -438,7 +562,7 @@ class Result: Parameters ---------- x : str - Label of scalar, vector, or tensor dataset to take absolute value of. + Name of scalar, vector, or tensor dataset to take absolute value of. """ self._add_generic_pointwise(self._add_absolute,{'x':x}) @@ -459,24 +583,51 @@ class Result: 'creator': 'add_calculation' } } - def add_calculation(self,label,formula,unit='n/a',description=None): + def add_calculation(self,name,formula,unit='n/a',description=None): """ Add result of a general formula. Parameters ---------- - label : str - Label of resulting dataset. + name : str + Name of resulting dataset. formula : str - Formula to calculate resulting dataset. Existing datasets are referenced by '#TheirLabel#'. + Formula to calculate resulting dataset. Existing datasets are referenced by '#TheirName#'. unit : str, optional Physical unit of the result. description : str, optional Human-readable description of the result. + Examples + -------- + Add total dislocation density, i.e. the sum of mobile dislocation + density 'rho_mob' and dislocation dipole density 'rho_dip' over + all slip systems: + + >>> import damask + >>> r = damask.Result('my_file.hdf5') + >>> r.add_calculation('rho_mob_total','np.sum(#rho_mob#,axis=1)', + ... '1/m²','total mobile dislocation density') + >>> r.add_calculation('rho_dip_total','np.sum(#rho_dip#,axis=1)', + ... '1/m²','total dislocation dipole density') + >>> r.add_calculation('rho_total','#rho_dip_total#+#rho_mob_total', + ... '1/m²','total dislocation density') + + Add Mises equivalent of the Cauchy stress without storage of + intermediate results. Define a user function for better readability: + + >>> import damask + >>> def equivalent_stress(F,P): + ... sigma = damask.mechanics.stress_Cauchy(F=F,P=P) + ... return damask.mechanics.equivalent_stress_Mises(sigma) + >>> r = damask.Result('my_file.hdf5') + >>> r.enable_user_function(equivalent_stress) + >>> r.add_calculation('sigma_vM','equivalent_stress(#F#,#P#)','Pa', + ... 'Mises equivalent of the Cauchy stress') + """ dataset_mapping = {d:d for d in set(re.findall(r'#(.*?)#',formula))} # datasets used in the formula - args = {'formula':formula,'label':label,'unit':unit,'description':description} + args = {'formula':formula,'label':name,'unit':unit,'description':description} self._add_generic_pointwise(self._add_calculation,dataset_mapping,args) @@ -500,9 +651,9 @@ class Result: Parameters ---------- P : str, optional - Label of the dataset containing the first Piola-Kirchhoff stress. Defaults to 'P'. + Name of the dataset containing the first Piola-Kirchhoff stress. Defaults to 'P'. F : str, optional - Label of the dataset containing the deformation gradient. Defaults to 'F'. + Name of the dataset containing the deformation gradient. Defaults to 'F'. """ self._add_generic_pointwise(self._add_stress_Cauchy,{'P':P,'F':F}) @@ -526,7 +677,15 @@ class Result: Parameters ---------- T : str - Label of tensor dataset. + Name of tensor dataset. + + Examples + -------- + Add the determinant of plastic deformation gradient 'F_p': + + >>> import damask + >>> r = damask.Result('my_file.hdf5') + >>> r.add_determinant('F_p') """ self._add_generic_pointwise(self._add_determinant,{'T':T}) @@ -550,7 +709,7 @@ class Result: Parameters ---------- T : str - Label of tensor dataset. + Name of tensor dataset. """ self._add_generic_pointwise(self._add_deviator,{'T':T}) @@ -581,7 +740,7 @@ class Result: Parameters ---------- T_sym : str - Label of symmetric tensor dataset. + Name of symmetric tensor dataset. eigenvalue : str, optional Eigenvalue. Select from 'max', 'mid', 'min'. Defaults to 'max'. @@ -614,7 +773,7 @@ class Result: Parameters ---------- T_sym : str - Label of symmetric tensor dataset. + Name of symmetric tensor dataset. eigenvalue : str, optional Eigenvalue to which the eigenvector corresponds. Select from 'max', 'mid', 'min'. Defaults to 'max'. @@ -654,9 +813,17 @@ class Result: l : numpy.array of shape (3) Lab frame direction for inverse pole figure. q : str - Label of the dataset containing the crystallographic orientation as quaternions. + Name of the dataset containing the crystallographic orientation as quaternions. Defaults to 'O'. + Examples + -------- + Add the IPF color along [0,1,1] for orientation 'O': + + >>> import damask + >>> r = damask.Result('my_file.hdf5') + >>> r.add_IPF_color(np.array([0,1,1])) + """ self._add_generic_pointwise(self._add_IPF_color,{'q':q},{'l':l}) @@ -679,7 +846,7 @@ class Result: Parameters ---------- T_sym : str - Label of symmetric tensor dataset. + Name of symmetric tensor dataset. """ self._add_generic_pointwise(self._add_maximum_shear,{'T_sym':T_sym}) @@ -713,11 +880,25 @@ class Result: Parameters ---------- T_sym : str - Label of symmetric tensorial stress or strain dataset. + Name of symmetric tensorial stress or strain dataset. kind : {'stress', 'strain', None}, optional Kind of the von Mises equivalent. Defaults to None, in which case it is selected based on the unit of the dataset ('1' -> strain, 'Pa' -> stress). + Examples + -------- + Add the Mises equivalent of the Cauchy stress 'sigma': + + >>> import damask + >>> r = damask.Result('my_file.hdf5') + >>> r.add_equivalent_Mises('sigma') + + Add the Mises equivalent of the spatial logarithmic strain 'epsilon_V^0.0(F)': + + >>> import damask + >>> r = damask.Result('my_file.hdf5') + >>> r.add_equivalent_Mises('epsilon_V^0.0(F)') + """ self._add_generic_pointwise(self._add_equivalent_Mises,{'T_sym':T_sym},{'kind':kind}) @@ -752,7 +933,7 @@ class Result: Parameters ---------- x : str - Label of vector or tensor dataset. + Name of vector or tensor dataset. ord : {non-zero int, inf, -inf, 'fro', 'nuc'}, optional Order of the norm. inf means NumPy’s inf object. For details refer to numpy.linalg.norm. @@ -780,9 +961,9 @@ class Result: Parameters ---------- P : str, optional - Label of first Piola-Kirchhoff stress dataset. Defaults to 'P'. + Name of first Piola-Kirchhoff stress dataset. Defaults to 'P'. F : str, optional - Label of deformation gradient dataset. Defaults to 'F'. + Name of deformation gradient dataset. Defaults to 'F'. """ self._add_generic_pointwise(self._add_stress_second_Piola_Kirchhoff,{'P':P,'F':F}) @@ -821,7 +1002,7 @@ class Result: # Parameters # ---------- # q : str - # Label of the dataset containing the crystallographic orientation as quaternions. + # Name of the dataset containing the crystallographic orientation as quaternions. # p : numpy.array of shape (3) # Crystallographic direction or plane. # polar : bool, optional @@ -848,8 +1029,16 @@ class Result: Parameters ---------- - F : str, optional - Label of deformation gradient dataset. + F : str + Name of deformation gradient dataset. + + Examples + -------- + Add the rotational part of deformation gradient 'F': + + >>> import damask + >>> r = damask.Result('my_file.hdf5') + >>> r.add_rotation('F') """ self._add_generic_pointwise(self._add_rotation,{'F':F}) @@ -873,7 +1062,15 @@ class Result: Parameters ---------- T : str - Label of tensor dataset. + Name of tensor dataset. + + Examples + -------- + Add the hydrostatic part of the Cauchy stress 'sigma': + + >>> import damask + >>> r = damask.Result('my_file.hdf5') + >>> r.add_spherical('sigma') """ self._add_generic_pointwise(self._add_spherical,{'T':T}) @@ -899,13 +1096,28 @@ class Result: Parameters ---------- F : str, optional - Label of deformation gradient dataset. Defaults to 'F'. + Name of deformation gradient dataset. Defaults to 'F'. t : {'V', 'U'}, optional Type of the polar decomposition, 'V' for left stretch tensor and 'U' for right stretch tensor. Defaults to 'V'. m : float, optional Order of the strain calculation. Defaults to 0.0. + Examples + -------- + Add the Biot strain based on the deformation gradient 'F': + + >>> import damask + >>> r = damask.Result('my_file.hdf5') + >>> r.strain(t='U',m=0.5) + + Add the plastic Euler-Almansi strain based on the + plastic deformation gradient 'F_p': + + >>> import damask + >>> r = damask.Result('my_file.hdf5') + >>> r.strain('F_p','V',-1) + """ self._add_generic_pointwise(self._add_strain,{'F':F},{'t':t,'m':m}) @@ -929,7 +1141,7 @@ class Result: Parameters ---------- F : str, optional - Label of deformation gradient dataset. Defaults to 'F'. + Name of deformation gradient dataset. Defaults to 'F'. t : {'V', 'U'}, optional Type of the polar decomposition, 'V' for left stretch tensor and 'U' for right stretch tensor. Defaults to 'V'. @@ -1036,10 +1248,14 @@ class Result: """ Write XDMF file to directly visualize data in DADF5 file. + The XDMF format is only supported for structured grids + with single phase and single constituent. + For other cases use `save_VTK`. + Parameters ---------- output : (list of) str - Labels of the datasets to read. + Names of the datasets included in the XDMF file. Defaults to '*', in which case all datasets are considered. """ @@ -1169,10 +1385,16 @@ class Result: """ Export to VTK cell/point data. + One VTK file per visible increment is created. + For cell data, the VTK format is a rectilinear grid (.vtr) for + grid-based simulations and an unstructured grid (.vtu) for + mesh-baed simulations. For point data, the VTK format is poly + data (.vtp). + Parameters ---------- output : (list of) str, optional - Labels of the datasets to place. + Names of the datasets included in the VTK file. Defaults to '*', in which case all datasets are exported. mode : {'cell', 'point'} Export in cell format or point format. @@ -1251,7 +1473,7 @@ class Result: Parameters ---------- output : (list of) str - Labels of the datasets to read. + Names of the datasets to read. Defaults to '*', in which case all datasets are read. flatten : bool Remove singular levels of the folder hierarchy. @@ -1303,7 +1525,7 @@ class Result: Parameters ---------- output : (list of) str, optional - Labels of the datasets to place. + Names of the datasets to read. Defaults to '*', in which case all datasets are placed. flatten : bool Remove singular levels of the folder hierarchy. diff --git a/python/damask/_table.py b/python/damask/_table.py index a068ec02a..dd6a981b7 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -49,7 +49,7 @@ class Table: Returns ------- - slice : Table + slice : damask.Table Sliced part of the Table. Examples @@ -157,7 +157,7 @@ class Table: Parameters ---------- - other : Table + other : damask.Table Table to compare against. rtol : float, optional Relative tolerance of equality. @@ -185,7 +185,7 @@ class Table: Parameters ---------- - other : Table + other : damask.Table Table to compare against. rtol : float, optional Relative tolerance of equality. diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index 340bd1ea3..e415d5e90 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -137,8 +137,8 @@ class VTK: fname : str or pathlib.Path Filename for reading. Valid extensions are .vtr, .vtu, .vtp, and .vtk. dataset_type : str, optional - Name of the vtk.vtkDataSet subclass when opening a .vtk file. Valid types are vtkRectilinearGrid, - vtkUnstructuredGrid, and vtkPolyData. + Name of the vtk.vtkDataSet subclass when opening a .vtk file. + Valid types are vtkRectilinearGrid, vtkUnstructuredGrid, and vtkPolyData. """ if not os.path.isfile(fname): # vtk has a strange error handling @@ -149,13 +149,13 @@ class VTK: reader.SetFileName(str(fname)) if dataset_type is None: raise TypeError('Dataset type for *.vtk file not given.') - elif dataset_type.lower().endswith('rectilineargrid'): + elif dataset_type.lower().endswith(('rectilineargrid','rectilinear_grid')): reader.Update() vtk_data = reader.GetRectilinearGridOutput() - elif dataset_type.lower().endswith('unstructuredgrid'): + elif dataset_type.lower().endswith(('unstructuredgrid','unstructured_grid')): reader.Update() vtk_data = reader.GetUnstructuredGridOutput() - elif dataset_type.lower().endswith('polydata'): + elif dataset_type.lower().endswith(('polydata','poly_data')): reader.Update() vtk_data = reader.GetPolyDataOutput() else: diff --git a/python/damask/mechanics.py b/python/damask/mechanics.py index 8512023fc..2396d969e 100644 --- a/python/damask/mechanics.py +++ b/python/damask/mechanics.py @@ -3,7 +3,7 @@ Finite-strain continuum mechanics. Notes ----- -Collection of routines to operate on numpy.ndarrays of shape (...,3,3). +All routines operate on numpy.ndarrays of shape (...,3,3). """ diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 0c34e7989..e79e25784 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -271,7 +271,7 @@ class TestResult: @pytest.mark.parametrize('overwrite',['off','on']) def test_add_overwrite(self,default,overwrite): - last = default.view('times',default.times_in_range(0,np.inf)[-1]) + last = default.view('increments',-1) last.add_stress_Cauchy() @@ -279,9 +279,9 @@ class TestResult: created_first = datetime.strptime(created_first,'%Y-%m-%d %H:%M:%S%z') if overwrite == 'on': - last = last.allow_modification() + last = last.modification_enable() else: - last = last.disallow_modification() + last = last.modification_disable() time.sleep(2.) try: @@ -301,14 +301,24 @@ class TestResult: def test_rename(self,default,allowed): if allowed == 'on': F = default.place('F') - default = default.allow_modification() + default = default.modification_enable() default.rename('F','new_name') assert np.all(F == default.place('new_name')) - default = default.disallow_modification() + default = default.modification_disable() with pytest.raises(PermissionError): default.rename('P','another_new_name') + @pytest.mark.parametrize('allowed',['off','on']) + def test_remove(self,default,allowed): + if allowed == 'on': + unsafe = default.modification_enable() + unsafe.remove('F') + assert unsafe.get('F') is None + else: + with pytest.raises(PermissionError): + default.remove('F') + @pytest.mark.parametrize('mode',['cell','node']) def test_coordinates(self,default,mode): if mode == 'cell': From 95831e53f621246c2f06ba1090fff26eca39a764 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 24 Apr 2021 14:47:52 +0200 Subject: [PATCH 200/219] using improved documentation --- PRIVATE | 2 +- python/damask/_grid.py | 36 ++++++++++++++++---------------- python/damask/_result.py | 2 ++ python/damask/_rotation.py | 2 +- python/damask/_vtk.py | 30 +++++++++++++++++++++++--- python/damask/grid_filters.py | 18 ++++++++++++++-- python/damask/mechanics.py | 2 -- python/damask/solver/__init__.py | 2 +- python/damask/tensor.py | 7 ++----- 9 files changed, 68 insertions(+), 33 deletions(-) diff --git a/PRIVATE b/PRIVATE index d58a002b0..156831f79 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit d58a002b0a43d240f143aee1396fdc766d87a886 +Subproject commit 156831f7962a1eb965023331a900121c5aee5e55 diff --git a/python/damask/_grid.py b/python/damask/_grid.py index 5f5bad63d..aebd8f92c 100644 --- a/python/damask/_grid.py +++ b/python/damask/_grid.py @@ -164,7 +164,7 @@ class Grid: Returns ------- loaded : damask.Grid - Geometry representation from file. + Grid-based geometry from file. """ v = VTK.load(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr') @@ -198,7 +198,7 @@ class Grid: Returns ------- loaded : damask.Grid - Geometry representation from file. + Grid-based geometry from file. """ warnings.warn('Support for ASCII-based geom format will be removed in DAMASK 3.1.0', DeprecationWarning,2) @@ -294,7 +294,7 @@ class Grid: Returns ------- loaded : damask.Grid - Geometry representation from file. + Grid-based geometry from file. """ b = util.DREAM3D_base_group(fname) if base_group is None else base_group @@ -336,7 +336,7 @@ class Grid: Returns ------- new : damask.Grid - Geometry representation from values in table. + Grid-based geometry from values in table. """ cells,size,origin = grid_filters.cellsSizeOrigin_coordinates0_point(table.get(coordinates)) @@ -378,7 +378,7 @@ class Grid: Returns ------- new : damask.Grid - Geometry representation from tessellation. + Grid-based geometry from tessellation. """ if periodic: @@ -432,7 +432,7 @@ class Grid: Returns ------- new : damask.Grid - Geometry representation from tessellation. + Grid-based geometry from tessellation. """ coords = grid_filters.coordinates0_point(cells,size).reshape(-1,3) @@ -510,7 +510,7 @@ class Grid: Returns ------- new : damask.Grid - Geometry representation defined by a minimal surface. + Grid-based geometry from definition of minimal surface. Notes ----- @@ -635,7 +635,7 @@ class Grid: Returns ------- updated : damask.Grid - Updated geometry representation. + Updated grid-based geometry. """ # radius and center @@ -680,7 +680,7 @@ class Grid: Returns ------- updated : damask.Grid - Updated geometry representation. + Updated grid-based geometry. """ valid = ['x','y','z'] @@ -717,7 +717,7 @@ class Grid: Returns ------- updated : damask.Grid - Updated geometry representation. + Updated grid-based geometry. """ valid = ['x','y','z'] @@ -747,7 +747,7 @@ class Grid: Returns ------- updated : damask.Grid - Updated geometry representation. + Updated grid-based geometry. """ return Grid(material = ndimage.interpolation.zoom( @@ -780,7 +780,7 @@ class Grid: Returns ------- updated : damask.Grid - Updated geometry representation. + Updated grid-based geometry. """ def mostFrequent(arr,selection=None): @@ -811,7 +811,7 @@ class Grid: Returns ------- updated : damask.Grid - Updated geometry representation. + Updated grid-based geometry. """ _,renumbered = np.unique(self.material,return_inverse=True) @@ -837,7 +837,7 @@ class Grid: Returns ------- updated : damask.Grid - Updated geometry representation. + Updated grid-based geometry. """ if fill is None: fill = np.nanmax(self.material) + 1 @@ -877,7 +877,7 @@ class Grid: Returns ------- updated : damask.Grid - Updated geometry representation. + Updated grid-based geometry. """ if offset is None: offset = 0 @@ -914,7 +914,7 @@ class Grid: Returns ------- updated : damask.Grid - Updated geometry representation. + Updated grid-based geometry. """ def mp(entry,mapper): @@ -937,7 +937,7 @@ class Grid: Returns ------- updated : damask.Grid - Updated geometry representation. + Updated grid-based geometry. """ a = self.material.flatten(order='F') @@ -977,7 +977,7 @@ class Grid: Returns ------- updated : damask.Grid - Updated geometry representation. + Updated grid-based geometry. """ def tainted_neighborhood(stencil,trigger): diff --git a/python/damask/_result.py b/python/damask/_result.py index 62ee2d8fe..bc3d3916d 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -277,6 +277,7 @@ class Result: ------- increments : list of ints Increment number of all increments within the given bounds. + """ # compatibility hack ln = 3 if self.version_minor < 12 else 10 @@ -303,6 +304,7 @@ class Result: ------- times : list of float Simulation time of all increments within the given bounds. + """ selected = [] for i,time in enumerate(self.times): diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 47ac59eb3..6b2869033 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -24,7 +24,7 @@ class Rotation: - Euler angle triplets are implemented using the Bunge convention, with angular ranges of [0,2π], [0,π], [0,2π]. - The rotation angle ω is limited to the interval [0,π]. - - The real part of a quaternion is positive, Re(q) > 0 + - The real part of a quaternion is positive, Re(q) ≥ 0 - P = -1 (as default). Examples diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index e415d5e90..2a6cbd3f2 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -3,7 +3,6 @@ import multiprocessing as mp from pathlib import Path import numpy as np -import numpy.ma as ma import vtk from vtk.util.numpy_support import numpy_to_vtk as np_to_vtk from vtk.util.numpy_support import numpy_to_vtkIdTypeArray as np_to_vtkIdTypeArray @@ -51,6 +50,11 @@ class VTK: origin : iterable of float, len (3), optional Spatial origin coordinates. + Returns + ------- + new : damask.VTK + VTK-based geometry without nodal or cell data. + """ vtk_data = vtk.vtkRectilinearGrid() vtk_data.SetDimensions(*(np.array(grid)+1)) @@ -68,7 +72,7 @@ class VTK: """ Create VTK of type vtk.vtkUnstructuredGrid. - This is the common type for FEM solver results. + This is the common type for mesh solver results. Parameters ---------- @@ -80,6 +84,11 @@ class VTK: cell_type : str Name of the vtk.vtkCell subclass. Tested for TRIANGLE, QUAD, TETRA, and HEXAHEDRON. + Returns + ------- + new : damask.VTK + VTK-based geometry without nodal or cell data. + """ vtk_nodes = vtk.vtkPoints() vtk_nodes.SetData(np_to_vtk(nodes)) @@ -110,6 +119,11 @@ class VTK: points : numpy.ndarray of shape (:,3) Spatial position of the points. + Returns + ------- + new : damask.VTK + VTK-based geometry without nodal or cell data. + """ N = points.shape[0] vtk_points = vtk.vtkPoints() @@ -140,6 +154,11 @@ class VTK: Name of the vtk.vtkDataSet subclass when opening a .vtk file. Valid types are vtkRectilinearGrid, vtkUnstructuredGrid, and vtkPolyData. + Returns + ------- + loaded : damask.VTK + VTK-based geometry from file. + """ if not os.path.isfile(fname): # vtk has a strange error handling raise FileNotFoundError(f'no such file: {fname}') @@ -246,7 +265,7 @@ class VTK: raise ValueError('No label defined for numpy.ndarray') N_data = data.shape[0] - data_ = np.where(data.mask,data.fill_value,data) if isinstance(data,ma.MaskedArray) else\ + data_ = np.where(data.mask,data.fill_value,data) if isinstance(data,np.ma.MaskedArray) else\ data d = np_to_vtk((data_.astype(np.single) if data_.dtype in [np.double, np.longdouble] else data_).reshape(N_data,-1),deep=True) # avoid large files @@ -277,6 +296,11 @@ class VTK: label : str Data label. + Returns + ------- + data : numpy.ndarray + Data stored under the given label. + """ cell_data = self.vtk_data.GetCellData() for a in range(cell_data.GetNumberOfArrays()): diff --git a/python/damask/grid_filters.py b/python/damask/grid_filters.py index d82f25ea9..fe5e290c6 100644 --- a/python/damask/grid_filters.py +++ b/python/damask/grid_filters.py @@ -1,8 +1,6 @@ """ Filters for operations on regular grids. -Notes ------ The grids are defined as (x,y,z,...) where x is fastest and z is slowest. This convention is consistent with the layout in grid vtr files. @@ -263,6 +261,11 @@ def cellsSizeOrigin_coordinates0_point(coordinates0,ordered=True): Expect coordinates0 data to be ordered (x fast, z slow). Defaults to True. + Returns + ------- + DNA : tuple with 3 numpy.ndarray of shape (3) + Information to reconstruct grid: cells, size, origin. + """ coords = [_np.unique(coordinates0[:,i]) for i in range(3)] mincorner = _np.array(list(map(min,coords))) @@ -415,6 +418,11 @@ def cellsSizeOrigin_coordinates0_node(coordinates0,ordered=True): Expect coordinates0 data to be ordered (x fast, z slow). Defaults to True. + Returns + ------- + DNA : tuple with 3 numpy.ndarray of shape (3) + Information to reconstruct grid: cells, size, origin. + """ coords = [_np.unique(coordinates0[:,i]) for i in range(3)] mincorner = _np.array(list(map(min,coords))) @@ -452,6 +460,7 @@ def point_to_node(cell_data): ------- node_data : numpy.ndarray of shape (:,:,:,...) Data defined on the nodes of a periodic grid. + """ n = ( cell_data + _np.roll(cell_data,1,(0,1,2)) + _np.roll(cell_data,1,(0,)) + _np.roll(cell_data,1,(1,)) + _np.roll(cell_data,1,(2,)) @@ -491,6 +500,11 @@ def coordinates0_valid(coordinates0): coordinates0 : numpy.ndarray Array of undeformed cell coordinates. + Returns + ------- + valid : bool + Wheter the coordinates lie on a regular grid. + """ try: cellsSizeOrigin_coordinates0_point(coordinates0,ordered=True) diff --git a/python/damask/mechanics.py b/python/damask/mechanics.py index 2396d969e..6ba785df1 100644 --- a/python/damask/mechanics.py +++ b/python/damask/mechanics.py @@ -1,8 +1,6 @@ """ Finite-strain continuum mechanics. -Notes ------ All routines operate on numpy.ndarrays of shape (...,3,3). """ diff --git a/python/damask/solver/__init__.py b/python/damask/solver/__init__.py index 298adb1f7..01cfeed9b 100644 --- a/python/damask/solver/__init__.py +++ b/python/damask/solver/__init__.py @@ -1,3 +1,3 @@ -"""Tools to control the various solvers.""" +"""Run simulations directly from python.""" from ._marc import Marc # noqa diff --git a/python/damask/tensor.py b/python/damask/tensor.py index 00fc7e72a..cf5d94020 100644 --- a/python/damask/tensor.py +++ b/python/damask/tensor.py @@ -1,10 +1,7 @@ """ -Tensor operations. +Tensor mathematics. -Notes ------ -This is not a tensor class, but a collection of routines -to operate on numpy.ndarrays of shape (...,3,3). +All routines operate on numpy.ndarrays of shape (...,3,3). """ From 24046ef6830e2fea4751efe3c4059d477853986c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 24 Apr 2021 18:00:57 +0200 Subject: [PATCH 201/219] support the user --- PRIVATE | 2 +- python/damask/__init__.py | 12 ++--- python/damask/_colormap.py | 15 ++++++ python/damask/grid_filters.py | 8 +-- python/damask/seeds.py | 12 ++--- python/damask/util.py | 91 ++++++++++++++++++++++++++++++++--- 6 files changed, 113 insertions(+), 27 deletions(-) diff --git a/PRIVATE b/PRIVATE index 156831f79..afffa8d04 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 156831f7962a1eb965023331a900121c5aee5e55 +Subproject commit afffa8d04e110282e514a4e57d0bad9c76effe01 diff --git a/python/damask/__init__.py b/python/damask/__init__.py index af9933954..ad46d454f 100644 --- a/python/damask/__init__.py +++ b/python/damask/__init__.py @@ -1,11 +1,4 @@ -""" -Tools for pre and post processing of DAMASK simulations. - -Modules that contain only one class (of the same name), -are prefixed by a '_'. For example, '_colormap' contains -a class called 'Colormap' which is imported as 'damask.Colormap'. - -""" +"""Tools for managing DAMASK simulations.""" from pathlib import Path as _Path import re as _re @@ -15,7 +8,6 @@ with open(_Path(__file__).parent/_Path('VERSION')) as _f: version = _re.sub(r'^v','',_f.readline().strip()) __version__ = version -# make classes directly accessible as damask.Class from . import util # noqa from . import seeds # noqa from . import tensor # noqa @@ -23,6 +15,8 @@ from . import mechanics # noqa from . import solver # noqa from . import grid_filters # noqa from . import lattice # noqa +#Modules that contain only one class (of the same name), are prefixed by a '_'. +#For example, '_colormap' containsa class called 'Colormap' which is imported as 'damask.Colormap'. from ._rotation import Rotation # noqa from ._orientation import Orientation # noqa from ._table import Table # noqa diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index 0d36c1ee6..02e2b922c 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -96,6 +96,11 @@ class Colormap(mpl.colors.ListedColormap): new : damask.Colormap Colormap within given bounds. + Examples + -------- + >>> import damask + >>> damask.Colormap.from_range((0,0,1),(0,0,0),'blue_to_black') + """ low_high = np.vstack((low,high)) if model.lower() == 'rgb': @@ -160,6 +165,11 @@ class Colormap(mpl.colors.ListedColormap): new : damask.Colormap Predefined colormap. + Examples + -------- + >>> import damask + >>> damask.Colormap.from_predefined('strain') + """ # matplotlib presets try: @@ -230,6 +240,11 @@ class Colormap(mpl.colors.ListedColormap): damask.Colormap The reversed colormap. + Examples + -------- + >>> import damask + >>> damask.Colormap.from_predefined('stress').reversed() + """ rev = super(Colormap,self).reversed(name) return Colormap(np.array(rev.colors),rev.name[:-4] if rev.name.endswith('_r_r') else rev.name) diff --git a/python/damask/grid_filters.py b/python/damask/grid_filters.py index fe5e290c6..bc9194947 100644 --- a/python/damask/grid_filters.py +++ b/python/damask/grid_filters.py @@ -263,8 +263,8 @@ def cellsSizeOrigin_coordinates0_point(coordinates0,ordered=True): Returns ------- - DNA : tuple with 3 numpy.ndarray of shape (3) - Information to reconstruct grid: cells, size, origin. + cells, size, origin : Three numpy.ndarray, each of shape (3) + Information to reconstruct grid. """ coords = [_np.unique(coordinates0[:,i]) for i in range(3)] @@ -420,8 +420,8 @@ def cellsSizeOrigin_coordinates0_node(coordinates0,ordered=True): Returns ------- - DNA : tuple with 3 numpy.ndarray of shape (3) - Information to reconstruct grid: cells, size, origin. + cells, size, origin : Three numpy.ndarray, each of shape (3) + Information to reconstruct grid. """ coords = [_np.unique(coordinates0[:,i]) for i in range(3)] diff --git a/python/damask/seeds.py b/python/damask/seeds.py index 74d15f1ef..aeab2e64a 100644 --- a/python/damask/seeds.py +++ b/python/damask/seeds.py @@ -26,8 +26,8 @@ def from_random(size,N_seeds,cells=None,rng_seed=None): Returns ------- - new : numpy.ndarray of shape (N_seeds,3) - Coordinates in 3D space. + coords : numpy.ndarray of shape (N_seeds,3) + Seed coordinates in 3D space. """ rng = _np.random.default_rng(rng_seed) @@ -63,8 +63,8 @@ def from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=True,rng_seed= Returns ------- - new : numpy.ndarray of shape (N_seeds,3) - Coordinates in 3D space. + coords : numpy.ndarray of shape (N_seeds,3) + Seed coordinates in 3D space. """ rng = _np.random.default_rng(rng_seed) @@ -106,8 +106,8 @@ def from_grid(grid,selection=None,invert=False,average=False,periodic=True): Returns ------- - new : numpy.ndarray of shape (...,3) - Coordinates in 3D space. + coords, materials : numpy.ndarray of shape (:,3), numpy.ndarray of shape (:) + Seed coordinates in 3D space, material IDs. """ material = grid.material.reshape((-1,1),order='F') diff --git a/python/damask/util.py b/python/damask/util.py index b519fb15e..fcf41c251 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -49,7 +49,7 @@ _colors = { #################################################################################################### def srepr(arg,glue = '\n'): r""" - Join arguments with glue string. + Join items with glue string. Parameters ---------- @@ -58,6 +58,11 @@ def srepr(arg,glue = '\n'): glue : str, optional Glue used for joining operation. Defaults to \n. + Returns + ------- + joined : str + String representation of the joined items. + """ if (not hasattr(arg, 'strip') and (hasattr(arg, '__getitem__') or @@ -68,19 +73,71 @@ def srepr(arg,glue = '\n'): def emph(what): - """Formats string with emphasis.""" + """ + Format with emphasis. + + Parameters + ---------- + what : object with __repr__ or iterable of objects with __repr__. + Message to format. + + Returns + ------- + formatted : str + Formatted string representation of the joined items. + + """ return _colors['bold']+srepr(what)+_colors['end_color'] def deemph(what): - """Formats string with deemphasis.""" + """ + Format with deemphasis. + + Parameters + ---------- + what : object with __repr__ or iterable of objects with __repr__. + Message to format. + + Returns + ------- + formatted : str + Formatted string representation of the joined items. + + """ return _colors['dim']+srepr(what)+_colors['end_color'] def warn(what): - """Formats string for warning.""" + """ + Format for warning. + + Parameters + ---------- + what : object with __repr__ or iterable of objects with __repr__. + Message to format. + + Returns + ------- + formatted : str + Formatted string representation of the joined items. + + """ return _colors['warning']+emph(what)+_colors['end_color'] def strikeout(what): - """Formats string as strikeout.""" + """ + Format as strikeout. + + Parameters + ---------- + what : object with __repr__ or iterable of objects with __repr__. + Message to format. + + Returns + ------- + formatted : str + Formatted string representation of the joined items. + + """ return _colors['crossout']+srepr(what)+_colors['end_color'] @@ -97,6 +154,11 @@ def execute(cmd,wd='./',env=None): env : dict, optional Environment for execution. + Returns + ------- + stdout, stderr : str + Output of the executed command. + """ print(f"executing '{cmd}' in '{wd}'") process = subprocess.run(shlex.split(cmd), @@ -157,6 +219,11 @@ def scale_to_coprime(v): v : numpy.ndarray of shape (:) Vector to scale. + Returns + ------- + m : numpy.ndarray of shape (:) + Vector scaled to co-prime numbers. + """ MAX_DENOMINATOR = 1000000 @@ -371,9 +438,14 @@ def DREAM3D_base_group(fname): Parameters ---------- - fname : str + fname : str or pathlib.Path Filename of the DREAM.3D (HDF5) file. + Returns + ------- + path : str + Path to the base group. + """ with h5py.File(fname,'r') as f: base_group = f.visit(lambda path: path.rsplit('/',2)[0] if '_SIMPL_GEOMETRY/SPACING' in path else None) @@ -393,9 +465,14 @@ def DREAM3D_cell_data_group(fname): Parameters ---------- - fname : str + fname : str or pathlib.Path Filename of the DREAM.3D (HDF5) file. + Returns + ------- + path : str + Path to the cell data group. + """ base_group = DREAM3D_base_group(fname) with h5py.File(fname,'r') as f: From 690b478013758459d25a9227cbd223145dde6bc2 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Sat, 24 Apr 2021 13:12:44 -0400 Subject: [PATCH 202/219] [skip ci] language polishing --- python/damask/_result.py | 32 ++++++++++++++++---------------- python/damask/_vtk.py | 6 +++--- python/damask/grid_filters.py | 4 ++-- python/damask/solver/__init__.py | 2 +- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index bc3d3916d..0ca160922 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -59,17 +59,17 @@ class Result: """ Add data to and export data from a DADF5 file. - A DADF5 (DAMASK HDF5) file contain DAMASK results. + A DADF5 (DAMASK HDF5) file contains DAMASK results. Its group/folder structure reflects the layout in material.yaml. - This class provides a customable view on the DADF5 file. + This class provides a customizable view on the DADF5 file. Upon initialization, all attributes are visible. Derived quantities are added to the file and existing data is exported based on the current view. Examples -------- - Open 'my_file.hdf5', which needs to contain deformation gradient 'F' + Open 'my_file.hdf5', which is assumed to contain deformation gradient 'F' and first Piola-Kirchhoff stress 'P', add the Mises equivalent of the Cauchy stress, and export it to VTK (file) and numpy.ndarray (memory). @@ -234,12 +234,12 @@ class Result: def modification_enable(self): """ - Allow to modify existing data. + Allow modification of existing data. Returns ------- modified_view : damask.Result - View where data is not write-protected. + View without write-protection of existing data. """ print(util.warn('Warning: Modification of existing datasets allowed!')) @@ -249,12 +249,12 @@ class Result: def modification_disable(self): """ - Disallow to modify existing data (default case). + Prevent modification of existing data (default case). Returns ------- modified_view : damask.Result - View where data is write-protected. + View with write-protection of existing data. """ dup = self.copy() @@ -328,7 +328,7 @@ class Result: Returns ------- view : damask.Result - View with where selected attributes are visible. + View with only the selected attributes being visible. Examples -------- @@ -338,7 +338,7 @@ class Result: >>> r = damask.Result('my_file.hdf5') >>> r_first = r.view('increment',0) - Get a view that shows all results of in simulation time [10,40]: + Get a view that shows all results between simulation times of 10 to 40: >>> import damask >>> r = damask.Result('my_file.hdf5') @@ -363,7 +363,7 @@ class Result: Returns ------- modified_view : damask.Result - View with more visible attributes. + View with additional visible attributes. Examples -------- @@ -380,7 +380,7 @@ class Result: def view_less(self,what,datasets): """ - Delete from view. + Remove from view. Parameters ---------- @@ -393,11 +393,11 @@ class Result: Returns ------- modified_view : damask.Result - View with less visible attributes. + View with fewer visible attributes. Examples -------- - Get a view that does not show the undeformed configuration: + Get a view that omits the undeformed configuration: >>> import damask >>> r_all = damask.Result('my_file.hdf5') @@ -1396,7 +1396,7 @@ class Result: Parameters ---------- output : (list of) str, optional - Names of the datasets included in the VTK file. + Names of the datasets to export to the VTK file. Defaults to '*', in which case all datasets are exported. mode : {'cell', 'point'} Export in cell format or point format. @@ -1521,7 +1521,7 @@ class Result: in the DADF5 file. Multi-phase data is fused into a single output. - `place` is equivalent to `read` if only one phase/homogenization + `place` is equivalent to `get` if only one phase/homogenization and one constituent is present. Parameters @@ -1537,7 +1537,7 @@ class Result: Remove branches with no data. Defaults to True. constituents : (list of) int, optional Constituents to consider. - Defaults to 'None', in which case all constituents are considered. + Defaults to None, in which case all constituents are considered. fill_float : float Fill value for non-existent entries of floating point type. Defaults to NaN. diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index 2a6cbd3f2..61f3efd80 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -46,9 +46,9 @@ class VTK: grid : iterable of int, len (3) Number of cells along each dimension. size : iterable of float, len (3) - Physical lengths along each dimension. + Physical length along each dimension. origin : iterable of float, len (3), optional - Spatial origin coordinates. + Coordinates of grid origin. Returns ------- @@ -161,7 +161,7 @@ class VTK: """ if not os.path.isfile(fname): # vtk has a strange error handling - raise FileNotFoundError(f'no such file: {fname}') + raise FileNotFoundError(f'No such file: {fname}') ext = Path(fname).suffix if ext == '.vtk' or dataset_type is not None: reader = vtk.vtkGenericDataObjectReader() diff --git a/python/damask/grid_filters.py b/python/damask/grid_filters.py index bc9194947..7d0bdab64 100644 --- a/python/damask/grid_filters.py +++ b/python/damask/grid_filters.py @@ -493,7 +493,7 @@ def node_to_point(node_data): def coordinates0_valid(coordinates0): """ - Check whether coordinates lie on a regular grid. + Check whether coordinates form a regular grid. Parameters ---------- @@ -503,7 +503,7 @@ def coordinates0_valid(coordinates0): Returns ------- valid : bool - Wheter the coordinates lie on a regular grid. + Whether the coordinates form a regular grid. """ try: diff --git a/python/damask/solver/__init__.py b/python/damask/solver/__init__.py index 01cfeed9b..bd92ee9a8 100644 --- a/python/damask/solver/__init__.py +++ b/python/damask/solver/__init__.py @@ -1,3 +1,3 @@ -"""Run simulations directly from python.""" +"""Run simulations directly from Python.""" from ._marc import Marc # noqa From 18aa6f7f1234c3a6c357447496baad2eb3183c03 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 24 Apr 2021 21:24:26 +0200 Subject: [PATCH 203/219] support for string arrays allows to add phase label from mapping. Only scalar string arrays are allowed (no real restriction) --- python/damask/_result.py | 4 ++-- python/damask/_vtk.py | 32 +++++++++++++++++++++++++------- python/tests/test_VTK.py | 12 ++++++++++++ 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 2c6cb7285..18ad93fd6 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1352,12 +1352,12 @@ class Result: at_cell_ph = [] in_data_ph = [] for c in range(self.N_constituents): - at_cell_ph.append({label: np.where(f['/'.join(['cell_to','phase'])][:,c]['label'] == label.encode())[0] \ + at_cell_ph.append({label: np.where(self.phase[:,c] == label)[0] \ for label in self.visible['phases']}) in_data_ph.append({label: f['/'.join(['cell_to','phase'])]['entry'][at_cell_ph[c][label]][:,c] \ for label in self.visible['phases']}) - at_cell_ho = {label: np.where(f['/'.join(['cell_to','homogenization'])][:]['label'] == label.encode())[0] \ + at_cell_ho = {label: np.where(self.homogenization[:] == label)[0] \ for label in self.visible['homogenizations']} in_data_ho = {label: f['/'.join(['cell_to','homogenization'])]['entry'][at_cell_ho[label]] \ for label in self.visible['homogenizations']} diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index 2a6cbd3f2..f8a4c47fc 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -265,10 +265,18 @@ class VTK: raise ValueError('No label defined for numpy.ndarray') N_data = data.shape[0] - data_ = np.where(data.mask,data.fill_value,data) if isinstance(data,np.ma.MaskedArray) else\ - data - d = np_to_vtk((data_.astype(np.single) if data_.dtype in [np.double, np.longdouble] else - data_).reshape(N_data,-1),deep=True) # avoid large files + data_ = (data if not isinstance(data,np.ma.MaskedArray) else + np.where(data.mask,data.fill_value,data)).reshape(N_data,-1) + + if data_.dtype in [np.double,np.longdouble]: + d = np_to_vtk(data_.astype(np.single),deep=True) # avoid large files + elif data_.dtype.type is np.str_: + d = vtk.vtkStringArray() + for s in np.squeeze(data_): + d.InsertNextValue(s) + else: + d = np_to_vtk(data_,deep=True) + d.SetName(label) if N_data == N_points: @@ -305,14 +313,24 @@ class VTK: cell_data = self.vtk_data.GetCellData() for a in range(cell_data.GetNumberOfArrays()): if cell_data.GetArrayName(a) == label: - return vtk_to_np(cell_data.GetArray(a)) + try: + return vtk_to_np(cell_data.GetArray(a)) + except AttributeError: + vtk_array = cell_data.GetAbstractArray(a) # string array point_data = self.vtk_data.GetPointData() for a in range(point_data.GetNumberOfArrays()): if point_data.GetArrayName(a) == label: - return vtk_to_np(point_data.GetArray(a)) + try: + return vtk_to_np(point_data.GetArray(a)) + except AttributeError: + vtk_array = point_data.GetAbstractArray(a) # string array - raise ValueError(f'Array "{label}" not found.') + try: + # string array + return np.array([vtk_array.GetValue(i) for i in range(vtk_array.GetNumberOfValues())]).astype(str) + except UnboundLocalError: + raise ValueError(f'Array "{label}" not found.') def get_comments(self): diff --git a/python/tests/test_VTK.py b/python/tests/test_VTK.py index 4328dc810..d4606d5c1 100644 --- a/python/tests/test_VTK.py +++ b/python/tests/test_VTK.py @@ -135,6 +135,18 @@ class TestVTK: with pytest.raises(TypeError): default.add('invalid_type','valid') + @pytest.mark.parametrize('data_type,shape',[(float,(3,)), + (float,(3,3)), + (float,(1,)), + (int,(4,)), + (str,(1,))]) + @pytest.mark.parametrize('N_values',[5*6*7,6*7*8]) + def test_add_get(self,default,data_type,shape,N_values): + data = np.squeeze(np.random.randint(0,100,(N_values,)+shape)).astype(data_type) + default.add(data,'data') + assert (np.squeeze(data.reshape(N_values,-1)) == default.get('data')).all() + + def test_add_masked(self,default): data = np.random.rand(5*6*7,3) masked = ma.MaskedArray(data,mask=data<.4,fill_value=42.) From 0459f17f583458652766c165779190d59f43410a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 25 Apr 2021 07:47:00 +0200 Subject: [PATCH 204/219] improved usability --- PRIVATE | 2 +- python/damask/_config.py | 15 +++++++++++++++ python/damask/_configmaterial.py | 17 ++++++++++++++++- python/damask/_grid.py | 5 +++++ python/damask/_result.py | 17 +++++++++-------- python/damask/_rotation.py | 10 +++++----- python/tests/test_Result.py | 14 +++++++------- 7 files changed, 58 insertions(+), 22 deletions(-) diff --git a/PRIVATE b/PRIVATE index afffa8d04..7f0594060 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit afffa8d04e110282e514a4e57d0bad9c76effe01 +Subproject commit 7f0594060779d9a8a4e774d558134309ab77b96e diff --git a/python/damask/_config.py b/python/damask/_config.py index 989f28fcd..627fc88c8 100644 --- a/python/damask/_config.py +++ b/python/damask/_config.py @@ -61,6 +61,11 @@ class Config(dict): other : damask.Config or dict Key-value pairs that update self. + Returns + ------- + updated : damask.Config + Updated configuration. + """ duplicate = self.copy() duplicate.update(other) @@ -81,6 +86,11 @@ class Config(dict): keys : iterable or scalar Label of the key(s) to remove. + Returns + ------- + updated : damask.Config + Updated configuration. + """ duplicate = self.copy() for k in keys if isinstance(keys, Iterable) and not isinstance(keys, str) else [keys]: @@ -98,6 +108,11 @@ class Config(dict): fname : file, str, or pathlib.Path Filename or file for writing. + Returns + ------- + loaded : damask.Config + Configuration from file. + """ try: fhandle = open(fname) diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index e927874f3..b5b38a417 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -54,7 +54,12 @@ class ConfigMaterial(Config): Parameters ---------- fname : file, str, or pathlib.Path, optional - Filename or file for writing. Defaults to 'material.yaml'. + Filename or file to read from. Defaults to 'material.yaml'. + + Returns + ------- + loaded : damask.ConfigMaterial + Material configuration from file. """ return super(ConfigMaterial,cls).load(fname) @@ -103,6 +108,11 @@ class ConfigMaterial(Config): and grain- or cell-wise data. Defaults to None, in which case it is set as the path that contains _SIMPL_GEOMETRY/SPACING. + Returns + ------- + loaded : damask.ConfigMaterial + Material configuration from file. + """ b = util.DREAM3D_base_group(fname) if base_group is None else base_group c = util.DREAM3D_cell_data_group(fname) if cell_data is None else cell_data @@ -146,6 +156,11 @@ class ConfigMaterial(Config): Keyword arguments where the key is the name and the value specifies the label of the data column in the table. + Returns + ------- + new : damask.ConfigMaterial + Material configuration from values in table. + Examples -------- >>> import damask diff --git a/python/damask/_grid.py b/python/damask/_grid.py index aebd8f92c..1b58870e4 100644 --- a/python/damask/_grid.py +++ b/python/damask/_grid.py @@ -1012,6 +1012,11 @@ class Grid: Direction(s) along which the boundaries are determined. Valid entries are 'x', 'y', 'z'. Defaults to 'xyz'. + Returns + ------- + grain_boundaries : damask.VTK + VTK-based geometry of grain boundary network. + """ valid = ['x','y','z'] if not set(directions).issubset(valid): diff --git a/python/damask/_result.py b/python/damask/_result.py index 0ca160922..f0f944790 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -585,16 +585,17 @@ class Result: 'creator': 'add_calculation' } } - def add_calculation(self,name,formula,unit='n/a',description=None): + def add_calculation(self,formula,name,unit='n/a',description=None): """ Add result of a general formula. Parameters ---------- - name : str - Name of resulting dataset. formula : str - Formula to calculate resulting dataset. Existing datasets are referenced by '#TheirName#'. + Formula to calculate resulting dataset. + Existing datasets are referenced by '#TheirName#'. + name : str + Name of resulting dataset. unit : str, optional Physical unit of the result. description : str, optional @@ -608,11 +609,11 @@ class Result: >>> import damask >>> r = damask.Result('my_file.hdf5') - >>> r.add_calculation('rho_mob_total','np.sum(#rho_mob#,axis=1)', + >>> r.add_calculation('np.sum(#rho_mob#,axis=1)','rho_mob_total', ... '1/m²','total mobile dislocation density') - >>> r.add_calculation('rho_dip_total','np.sum(#rho_dip#,axis=1)', + >>> r.add_calculation(''np.sum(#rho_dip#,axis=1)',rho_dip_total', ... '1/m²','total dislocation dipole density') - >>> r.add_calculation('rho_total','#rho_dip_total#+#rho_mob_total', + >>> r.add_calculation('#rho_dip_total#+#rho_mob_total','rho_total', ... '1/m²','total dislocation density') Add Mises equivalent of the Cauchy stress without storage of @@ -624,7 +625,7 @@ class Result: ... return damask.mechanics.equivalent_stress_Mises(sigma) >>> r = damask.Result('my_file.hdf5') >>> r.enable_user_function(equivalent_stress) - >>> r.add_calculation('sigma_vM','equivalent_stress(#F#,#P#)','Pa', + >>> r.add_calculation('equivalent_stress(#F#,#P#)','sigma_vM','Pa', ... 'Mises equivalent of the Cauchy stress') """ diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 6b2869033..3bd84fcb1 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -357,7 +357,7 @@ class Rotation: Parameters ---------- - other : damask.Rotation + other : damask.Rotation """ return self.copy(rotation=np.vstack(tuple(map(lambda x:x.quaternion, @@ -370,7 +370,7 @@ class Rotation: Returns ------- - flattened : damask.Rotation + flattened : damask.Rotation Rotation flattened to single dimension. """ @@ -383,7 +383,7 @@ class Rotation: Returns ------- - reshaped : damask.Rotation + reshaped : damask.Rotation Rotation of given shape. """ @@ -405,7 +405,7 @@ class Rotation: Returns ------- - broadcasted : damask.Rotation + broadcasted : damask.Rotation Rotation broadcasted to given shape. """ @@ -464,7 +464,7 @@ class Rotation: Returns ------- - g : damask.Rotation + g : damask.Rotation Misorientation. """ diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index e79e25784..56bc4a00f 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -110,14 +110,14 @@ class TestResult: def test_add_calculation(self,default,tmp_path,mode): if mode == 'direct': - default.add_calculation('x','2.0*np.abs(#F#)-1.0','-','my notes') + default.add_calculation('2.0*np.abs(#F#)-1.0','x','-','my notes') else: with open(tmp_path/'f.py','w') as f: f.write("import numpy as np\ndef my_func(field):\n return 2.0*np.abs(field)-1.0\n") sys.path.insert(0,str(tmp_path)) import f default.enable_user_function(f.my_func) - default.add_calculation('x','my_func(#F#)','-','my notes') + default.add_calculation('my_func(#F#)','x','-','my notes') in_memory = 2.0*np.abs(default.place('F'))-1.0 in_file = default.place('x') @@ -193,14 +193,14 @@ class TestResult: def test_add_Mises_invalid(self,default): default.add_stress_Cauchy('P','F') - default.add_calculation('sigma_y','#sigma#',unit='y') + default.add_calculation('#sigma#','sigma_y',unit='y') default.add_equivalent_Mises('sigma_y') assert default.get('sigma_y_vM') is None def test_add_Mises_stress_strain(self,default): default.add_stress_Cauchy('P','F') - default.add_calculation('sigma_y','#sigma#',unit='y') - default.add_calculation('sigma_x','#sigma#',unit='x') + default.add_calculation('#sigma#','sigma_y',unit='y') + default.add_calculation('#sigma#','sigma_x',unit='x') default.add_equivalent_Mises('sigma_y',kind='strain') default.add_equivalent_Mises('sigma_x',kind='stress') assert not np.allclose(default.place('sigma_y_vM'),default.place('sigma_x_vM')) @@ -285,7 +285,7 @@ class TestResult: time.sleep(2.) try: - last.add_calculation('sigma','#sigma#*0.0+311.','not the Cauchy stress') + last.add_calculation('#sigma#*0.0+311.','sigma','not the Cauchy stress') except ValueError: pass @@ -362,7 +362,7 @@ class TestResult: def test_XDMF(self,tmp_path,single_phase,update,ref_path): for shape in [('scalar',()),('vector',(3,)),('tensor',(3,3)),('matrix',(12,))]: for dtype in ['f4','f8','i1','i2','i4','i8','u1','u2','u4','u8']: - single_phase.add_calculation(f'{shape[0]}_{dtype}',f"np.ones(np.shape(#F#)[0:1]+{shape[1]},'{dtype}')") + single_phase.add_calculation(f"np.ones(np.shape(#F#)[0:1]+{shape[1]},'{dtype}')",f'{shape[0]}_{dtype}') fname = os.path.splitext(os.path.basename(single_phase.fname))[0]+'.xdmf' os.chdir(tmp_path) single_phase.save_XDMF() From 7250fbb7c6080335b9a670efd11a1fc47ef53d67 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 25 Apr 2021 08:06:12 +0200 Subject: [PATCH 205/219] DAMASK is compatible with PETSc 3.15 still need to update the test server (and DAMASK_interface.f90) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 198528b59..533b14e85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ include (FindPkgConfig REQUIRED) # Dummy project to determine compiler names and version project (Prerequisites LANGUAGES) set(ENV{PKG_CONFIG_PATH} "$ENV{PETSC_DIR}/$ENV{PETSC_ARCH}/lib/pkgconfig") -pkg_check_modules (PETSC REQUIRED PETSc>=3.12.0 PETSc<3.15.0) +pkg_check_modules (PETSC REQUIRED PETSc>=3.12.0 PETSc<3.16.0) pkg_get_variable (CMAKE_Fortran_COMPILER PETSc fcompiler) pkg_get_variable (CMAKE_C_COMPILER PETSc ccompiler) From d0b86f54fb280fbacb4012712da0579b93abb4d2 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 25 Apr 2021 08:06:52 +0200 Subject: [PATCH 206/219] consistent with new naming scheme --- src/DAMASK_interface.f90 | 4 +- src/phase.f90 | 16 +- src/phase_mechanical_plastic.f90 | 78 ++++----- ...phase_mechanical_plastic_dislotungsten.f90 | 62 +++---- src/phase_mechanical_plastic_dislotwin.f90 | 122 +++++++------- src/phase_mechanical_plastic_isotropic.f90 | 22 +-- ...phase_mechanical_plastic_kinehardening.f90 | 60 +++---- src/phase_mechanical_plastic_nonlocal.f90 | 158 +++++++++--------- ...phase_mechanical_plastic_phenopowerlaw.f90 | 52 +++--- src/phase_thermal.f90 | 58 +++---- src/phase_thermal_dissipation.f90 | 6 +- src/phase_thermal_externalheat.f90 | 14 +- 12 files changed, 325 insertions(+), 327 deletions(-) diff --git a/src/DAMASK_interface.f90 b/src/DAMASK_interface.f90 index b7cb1d80f..e01c050fa 100644 --- a/src/DAMASK_interface.f90 +++ b/src/DAMASK_interface.f90 @@ -51,9 +51,7 @@ subroutine DAMASK_interface_init #include #if PETSC_VERSION_MAJOR!=3 || PETSC_VERSION_MINORPETSC_MINOR_MAX -=================================================================================================== --- WRONG PETSc VERSION --- WRONG PETSc VERSION --- WRONG PETSc VERSION --- WRONG PETSc VERSION -- -=================================================================================================== +-- UNSUPPORTED PETSc VERSION --- UNSUPPORTED PETSc VERSION --- UNSUPPORTED PETSc VERSION --- #endif character(len=pPathLen*3+pStringLen) :: & diff --git a/src/phase.f90 b/src/phase.f90 index b65bf334f..93743d64a 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -161,13 +161,13 @@ module phase real(pReal), dimension(3,3) :: P end function phase_P - module function thermal_T(ph,me) result(T) - integer, intent(in) :: ph,me + module function thermal_T(ph,en) result(T) + integer, intent(in) :: ph,en real(pReal) :: T end function thermal_T - module function thermal_dot_T(ph,me) result(dot_T) - integer, intent(in) :: ph,me + module function thermal_dot_T(ph,en) result(dot_T) + integer, intent(in) :: ph,en real(pReal) :: dot_T end function thermal_dot_T @@ -216,10 +216,10 @@ module phase ! == cleaned:end =================================================================================== - module function thermal_stress(Delta_t,ph,me) result(converged_) + module function thermal_stress(Delta_t,ph,en) result(converged_) real(pReal), intent(in) :: Delta_t - integer, intent(in) :: ph, me + integer, intent(in) :: ph, en logical :: converged_ end function thermal_stress @@ -253,8 +253,8 @@ module phase f end function phase_f_phi - module function phase_f_T(ph,me) result(f) - integer, intent(in) :: ph, me + module function phase_f_T(ph,en) result(f) + integer, intent(in) :: ph, en real(pReal) :: f end function phase_f_T diff --git a/src/phase_mechanical_plastic.f90 b/src/phase_mechanical_plastic.f90 index 3ec275795..33dfd681f 100644 --- a/src/phase_mechanical_plastic.f90 +++ b/src/phase_mechanical_plastic.f90 @@ -37,7 +37,7 @@ submodule(phase:mechanical) plastic myPlasticity end function plastic_nonlocal_init - module subroutine isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) + module subroutine isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en) real(pReal), dimension(3,3), intent(out) :: & Lp real(pReal), dimension(3,3,3,3), intent(out) :: & @@ -46,10 +46,10 @@ submodule(phase:mechanical) plastic Mp integer, intent(in) :: & ph, & - me + en end subroutine isotropic_LpAndItsTangent - pure module subroutine phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) + pure module subroutine phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en) real(pReal), dimension(3,3), intent(out) :: & Lp real(pReal), dimension(3,3,3,3), intent(out) :: & @@ -58,10 +58,10 @@ submodule(phase:mechanical) plastic Mp integer, intent(in) :: & ph, & - me + en end subroutine phenopowerlaw_LpAndItsTangent - pure module subroutine kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) + pure module subroutine kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en) real(pReal), dimension(3,3), intent(out) :: & Lp real(pReal), dimension(3,3,3,3), intent(out) :: & @@ -70,10 +70,10 @@ submodule(phase:mechanical) plastic Mp integer, intent(in) :: & ph, & - me + en end subroutine kinehardening_LpAndItsTangent - module subroutine dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,ph,me) + module subroutine dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,ph,en) real(pReal), dimension(3,3), intent(out) :: & Lp real(pReal), dimension(3,3,3,3), intent(out) :: & @@ -85,10 +85,10 @@ submodule(phase:mechanical) plastic T integer, intent(in) :: & ph, & - me + en end subroutine dislotwin_LpAndItsTangent - pure module subroutine dislotungsten_LpAndItsTangent(Lp,dLp_dMp,Mp,T,ph,me) + pure module subroutine dislotungsten_LpAndItsTangent(Lp,dLp_dMp,Mp,T,ph,en) real(pReal), dimension(3,3), intent(out) :: & Lp real(pReal), dimension(3,3,3,3), intent(out) :: & @@ -100,11 +100,11 @@ submodule(phase:mechanical) plastic T integer, intent(in) :: & ph, & - me + en end subroutine dislotungsten_LpAndItsTangent module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, & - Mp,Temperature,ph,me) + Mp,Temperature,ph,en) real(pReal), dimension(3,3), intent(out) :: & Lp real(pReal), dimension(3,3,3,3), intent(out) :: & @@ -116,55 +116,55 @@ submodule(phase:mechanical) plastic Temperature integer, intent(in) :: & ph, & - me + en end subroutine nonlocal_LpAndItsTangent - module subroutine isotropic_dotState(Mp,ph,me) + module subroutine isotropic_dotState(Mp,ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress integer, intent(in) :: & ph, & - me + en end subroutine isotropic_dotState - module subroutine phenopowerlaw_dotState(Mp,ph,me) + module subroutine phenopowerlaw_dotState(Mp,ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress integer, intent(in) :: & ph, & - me + en end subroutine phenopowerlaw_dotState - module subroutine plastic_kinehardening_dotState(Mp,ph,me) + module subroutine plastic_kinehardening_dotState(Mp,ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress integer, intent(in) :: & ph, & - me + en end subroutine plastic_kinehardening_dotState - module subroutine dislotwin_dotState(Mp,T,ph,me) + module subroutine dislotwin_dotState(Mp,T,ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & T integer, intent(in) :: & ph, & - me + en end subroutine dislotwin_dotState - module subroutine dislotungsten_dotState(Mp,T,ph,me) + module subroutine dislotungsten_dotState(Mp,T,ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & T integer, intent(in) :: & ph, & - me + en end subroutine dislotungsten_dotState - module subroutine nonlocal_dotState(Mp,Temperature,timestep,ph,me,ip,el) + module subroutine nonlocal_dotState(Mp,Temperature,timestep,ph,en,ip,el) real(pReal), dimension(3,3), intent(in) :: & Mp !< MandelStress real(pReal), intent(in) :: & @@ -172,47 +172,47 @@ submodule(phase:mechanical) plastic timestep !< substepped crystallite time increment integer, intent(in) :: & ph, & - me, & + en, & ip, & !< current integration point el !< current element number end subroutine nonlocal_dotState - module subroutine dislotwin_dependentState(T,ph,me) + module subroutine dislotwin_dependentState(T,ph,en) integer, intent(in) :: & ph, & - me + en real(pReal), intent(in) :: & T end subroutine dislotwin_dependentState - module subroutine dislotungsten_dependentState(ph,me) + module subroutine dislotungsten_dependentState(ph,en) integer, intent(in) :: & ph, & - me + en end subroutine dislotungsten_dependentState - module subroutine nonlocal_dependentState(ph, me, ip, el) + module subroutine nonlocal_dependentState(ph, en, ip, el) integer, intent(in) :: & ph, & - me, & + en, & ip, & !< current integration point el !< current element number end subroutine nonlocal_dependentState - module subroutine plastic_kinehardening_deltaState(Mp,ph,me) + module subroutine plastic_kinehardening_deltaState(Mp,ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress integer, intent(in) :: & ph, & - me + en end subroutine plastic_kinehardening_deltaState - module subroutine plastic_nonlocal_deltaState(Mp,ph,me) + module subroutine plastic_nonlocal_deltaState(Mp,ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp integer, intent(in) :: & ph, & - me + en end subroutine plastic_nonlocal_deltaState end interface @@ -357,22 +357,22 @@ module subroutine plastic_dependentState(co, ip, el) integer :: & ph, & - me + en ph = material_phaseAt(co,el) - me = material_phasememberAt(co,ip,el) + en = material_phasememberAt(co,ip,el) plasticType: select case (phase_plasticity(material_phaseAt(co,el))) case (PLASTICITY_DISLOTWIN_ID) plasticType - call dislotwin_dependentState(thermal_T(ph,me),ph,me) + call dislotwin_dependentState(thermal_T(ph,en),ph,en) case (PLASTICITY_DISLOTUNGSTEN_ID) plasticType - call dislotungsten_dependentState(ph,me) + call dislotungsten_dependentState(ph,en) case (PLASTICITY_NONLOCAL_ID) plasticType - call nonlocal_dependentState(ph,me,ip,el) + call nonlocal_dependentState(ph,en,ip,el) end select plasticType diff --git a/src/phase_mechanical_plastic_dislotungsten.f90 b/src/phase_mechanical_plastic_dislotungsten.f90 index 2e7130756..aaa3885b9 100644 --- a/src/phase_mechanical_plastic_dislotungsten.f90 +++ b/src/phase_mechanical_plastic_dislotungsten.f90 @@ -17,7 +17,7 @@ submodule(phase:plastic) dislotungsten D_0 = 1.0_pReal, & !< prefactor for self-diffusion coefficient Q_cl = 1.0_pReal !< activation energy for dislocation climb real(pReal), allocatable, dimension(:) :: & - b_sl, & !< magnitude me Burgers vector [m] + b_sl, & !< magnitude en Burgers vector [m] D_a, & i_sl, & !< Adj. parameter for distance between 2 forest dislocations f_at, & !< factor to calculate atomic volume @@ -271,7 +271,7 @@ end function plastic_dislotungsten_init !> @brief Calculate plastic velocity gradient and its tangent. !-------------------------------------------------------------------------------------------------- pure module subroutine dislotungsten_LpAndItsTangent(Lp,dLp_dMp, & - Mp,T,ph,me) + Mp,T,ph,en) real(pReal), dimension(3,3), intent(out) :: & Lp !< plastic velocity gradient real(pReal), dimension(3,3,3,3), intent(out) :: & @@ -283,7 +283,7 @@ pure module subroutine dislotungsten_LpAndItsTangent(Lp,dLp_dMp, & T !< temperature integer, intent(in) :: & ph, & - me + en integer :: & i,k,l,m,n @@ -296,7 +296,7 @@ pure module subroutine dislotungsten_LpAndItsTangent(Lp,dLp_dMp, & associate(prm => param(ph)) - call kinetics(Mp,T,ph,me,dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg) + call kinetics(Mp,T,ph,en,dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg) do i = 1, prm%sum_N_sl Lp = Lp + (dot_gamma_pos(i)+dot_gamma_neg(i))*prm%P_sl(1:3,1:3,i) forall (k=1:3,l=1:3,m=1:3,n=1:3) & @@ -313,7 +313,7 @@ end subroutine dislotungsten_LpAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief Calculate the rate of change of microstructure. !-------------------------------------------------------------------------------------------------- -module subroutine dislotungsten_dotState(Mp,T,ph,me) +module subroutine dislotungsten_dotState(Mp,T,ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress @@ -321,7 +321,7 @@ module subroutine dislotungsten_dotState(Mp,T,ph,me) T !< temperature integer, intent(in) :: & ph, & - me + en real(pReal) :: & VacancyDiffusion @@ -337,11 +337,11 @@ module subroutine dislotungsten_dotState(Mp,T,ph,me) associate(prm => param(ph), stt => state(ph),& dot => dotState(ph), dst => dependentState(ph)) - call kinetics(Mp,T,ph,me,& + call kinetics(Mp,T,ph,en,& gdot_pos,gdot_neg, & tau_pos_out = tau_pos,tau_neg_out = tau_neg) - dot%gamma_sl(:,me) = (gdot_pos+gdot_neg) ! ToDo: needs to be abs + dot%gamma_sl(:,en) = (gdot_pos+gdot_neg) ! ToDo: needs to be abs VacancyDiffusion = prm%D_0*exp(-prm%Q_cl/(kB*T)) where(dEq0(tau_pos)) ! ToDo: use avg of pos and neg @@ -350,20 +350,20 @@ module subroutine dislotungsten_dotState(Mp,T,ph,me) else where dip_distance = math_clip(3.0_pReal*prm%mu*prm%b_sl/(16.0_pReal*PI*abs(tau_pos)), & prm%D_a, & ! lower limit - dst%Lambda_sl(:,me)) ! upper limit - dot_rho_dip_formation = merge(2.0_pReal*dip_distance* stt%rho_mob(:,me)*abs(dot%gamma_sl(:,me))/prm%b_sl, & ! ToDo: ignore region of spontaneous annihilation + dst%Lambda_sl(:,en)) ! upper limit + dot_rho_dip_formation = merge(2.0_pReal*dip_distance* stt%rho_mob(:,en)*abs(dot%gamma_sl(:,en))/prm%b_sl, & ! ToDo: ignore region of spontaneous annihilation 0.0_pReal, & prm%dipoleformation) v_cl = (3.0_pReal*prm%mu*VacancyDiffusion*prm%f_at/(2.0_pReal*pi*kB*T)) & * (1.0_pReal/(dip_distance+prm%D_a)) - dot_rho_dip_climb = (4.0_pReal*v_cl*stt%rho_dip(:,me))/(dip_distance-prm%D_a) ! ToDo: Discuss with Franz: Stress dependency? + dot_rho_dip_climb = (4.0_pReal*v_cl*stt%rho_dip(:,en))/(dip_distance-prm%D_a) ! ToDo: Discuss with Franz: Stress dependency? end where - dot%rho_mob(:,me) = abs(dot%gamma_sl(:,me))/(prm%b_sl*dst%Lambda_sl(:,me)) & ! multiplication + dot%rho_mob(:,en) = abs(dot%gamma_sl(:,en))/(prm%b_sl*dst%Lambda_sl(:,en)) & ! multiplication - dot_rho_dip_formation & - - (2.0_pReal*prm%D_a)/prm%b_sl*stt%rho_mob(:,me)*abs(dot%gamma_sl(:,me)) ! Spontaneous annihilation of 2 single edge dislocations - dot%rho_dip(:,me) = dot_rho_dip_formation & - - (2.0_pReal*prm%D_a)/prm%b_sl*stt%rho_dip(:,me)*abs(dot%gamma_sl(:,me)) & ! Spontaneous annihilation of a single edge dislocation with a dipole constituent + - (2.0_pReal*prm%D_a)/prm%b_sl*stt%rho_mob(:,en)*abs(dot%gamma_sl(:,en)) ! Spontaneous annihilation of 2 single edge dislocations + dot%rho_dip(:,en) = dot_rho_dip_formation & + - (2.0_pReal*prm%D_a)/prm%b_sl*stt%rho_dip(:,en)*abs(dot%gamma_sl(:,en)) & ! Spontaneous annihilation of a single edge dislocation with a dipole constituent - dot_rho_dip_climb end associate @@ -374,22 +374,22 @@ end subroutine dislotungsten_dotState !-------------------------------------------------------------------------------------------------- !> @brief Calculate derived quantities from state. !-------------------------------------------------------------------------------------------------- -module subroutine dislotungsten_dependentState(ph,me) +module subroutine dislotungsten_dependentState(ph,en) integer, intent(in) :: & ph, & - me + en real(pReal), dimension(param(ph)%sum_N_sl) :: & dislocationSpacing associate(prm => param(ph), stt => state(ph),dst => dependentState(ph)) - dislocationSpacing = sqrt(matmul(prm%forestProjection,stt%rho_mob(:,me)+stt%rho_dip(:,me))) - dst%threshold_stress(:,me) = prm%mu*prm%b_sl & - * sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,me)+stt%rho_dip(:,me))) + dislocationSpacing = sqrt(matmul(prm%forestProjection,stt%rho_mob(:,en)+stt%rho_dip(:,en))) + dst%threshold_stress(:,en) = prm%mu*prm%b_sl & + * sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,en)+stt%rho_dip(:,en))) - dst%Lambda_sl(:,me) = prm%D/(1.0_pReal+prm%D*dislocationSpacing/prm%i_sl) + dst%Lambda_sl(:,en) = prm%D/(1.0_pReal+prm%D*dislocationSpacing/prm%i_sl) end associate @@ -438,7 +438,7 @@ end subroutine plastic_dislotungsten_results ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end !-------------------------------------------------------------------------------------------------- -pure subroutine kinetics(Mp,T,ph,me, & +pure subroutine kinetics(Mp,T,ph,en, & dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg,tau_pos_out,tau_neg_out) real(pReal), dimension(3,3), intent(in) :: & @@ -447,7 +447,7 @@ pure subroutine kinetics(Mp,T,ph,me, & T !< temperature integer, intent(in) :: & ph, & - me + en real(pReal), intent(out), dimension(param(ph)%sum_N_sl) :: & dot_gamma_pos, & @@ -478,11 +478,11 @@ pure subroutine kinetics(Mp,T,ph,me, & if (present(tau_neg_out)) tau_neg_out = tau_neg associate(BoltzmannRatio => prm%Q_s/(kB*T), & - dot_gamma_0 => stt%rho_mob(:,me)*prm%b_sl*prm%v_0, & - effectiveLength => dst%Lambda_sl(:,me) - prm%w) + dot_gamma_0 => stt%rho_mob(:,en)*prm%b_sl*prm%v_0, & + effectiveLength => dst%Lambda_sl(:,en) - prm%w) - significantPositiveTau: where(abs(tau_pos)-dst%threshold_stress(:,me) > tol_math_check) - StressRatio = (abs(tau_pos)-dst%threshold_stress(:,me))/prm%tau_Peierls + significantPositiveTau: where(abs(tau_pos)-dst%threshold_stress(:,en) > tol_math_check) + StressRatio = (abs(tau_pos)-dst%threshold_stress(:,en))/prm%tau_Peierls StressRatio_p = StressRatio** prm%p StressRatio_pminus1 = StressRatio**(prm%p-1.0_pReal) needsGoodName = exp(-BoltzmannRatio*(1-StressRatio_p) ** prm%q) @@ -498,7 +498,7 @@ pure subroutine kinetics(Mp,T,ph,me, & end where significantPositiveTau if (present(ddot_gamma_dtau_pos)) then - significantPositiveTau2: where(abs(tau_pos)-dst%threshold_stress(:,me) > tol_math_check) + significantPositiveTau2: where(abs(tau_pos)-dst%threshold_stress(:,en) > tol_math_check) dtn = -1.0_pReal * t_n * BoltzmannRatio * prm%p * prm%q * (1.0_pReal-StressRatio_p)**(prm%q - 1.0_pReal) & * (StressRatio)**(prm%p - 1.0_pReal) / prm%tau_Peierls dtk = -1.0_pReal * t_k / tau_pos @@ -511,8 +511,8 @@ pure subroutine kinetics(Mp,T,ph,me, & end where significantPositiveTau2 endif - significantNegativeTau: where(abs(tau_neg)-dst%threshold_stress(:,me) > tol_math_check) - StressRatio = (abs(tau_neg)-dst%threshold_stress(:,me))/prm%tau_Peierls + significantNegativeTau: where(abs(tau_neg)-dst%threshold_stress(:,en) > tol_math_check) + StressRatio = (abs(tau_neg)-dst%threshold_stress(:,en))/prm%tau_Peierls StressRatio_p = StressRatio** prm%p StressRatio_pminus1 = StressRatio**(prm%p-1.0_pReal) needsGoodName = exp(-BoltzmannRatio*(1-StressRatio_p) ** prm%q) @@ -528,7 +528,7 @@ pure subroutine kinetics(Mp,T,ph,me, & end where significantNegativeTau if (present(ddot_gamma_dtau_neg)) then - significantNegativeTau2: where(abs(tau_neg)-dst%threshold_stress(:,me) > tol_math_check) + significantNegativeTau2: where(abs(tau_neg)-dst%threshold_stress(:,en) > tol_math_check) dtn = -1.0_pReal * t_n * BoltzmannRatio * prm%p * prm%q * (1.0_pReal-StressRatio_p)**(prm%q - 1.0_pReal) & * (StressRatio)**(prm%p - 1.0_pReal) / prm%tau_Peierls dtk = -1.0_pReal * t_k / tau_neg diff --git a/src/phase_mechanical_plastic_dislotwin.f90 b/src/phase_mechanical_plastic_dislotwin.f90 index b04f28f0e..151250f14 100644 --- a/src/phase_mechanical_plastic_dislotwin.f90 +++ b/src/phase_mechanical_plastic_dislotwin.f90 @@ -519,12 +519,12 @@ end function plastic_dislotwin_homogenizedC !-------------------------------------------------------------------------------------------------- !> @brief Calculate plastic velocity gradient and its tangent. !-------------------------------------------------------------------------------------------------- -module subroutine dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,ph,me) +module subroutine dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,ph,en) real(pReal), dimension(3,3), intent(out) :: Lp real(pReal), dimension(3,3,3,3), intent(out) :: dLp_dMp real(pReal), dimension(3,3), intent(in) :: Mp - integer, intent(in) :: ph,me + integer, intent(in) :: ph,en real(pReal), intent(in) :: T integer :: i,k,l,m,n @@ -565,13 +565,13 @@ module subroutine dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,ph,me) associate(prm => param(ph), stt => state(ph)) f_unrotated = 1.0_pReal & - - sum(stt%f_tw(1:prm%sum_N_tw,me)) & - - sum(stt%f_tr(1:prm%sum_N_tr,me)) + - sum(stt%f_tw(1:prm%sum_N_tw,en)) & + - sum(stt%f_tr(1:prm%sum_N_tr,en)) Lp = 0.0_pReal dLp_dMp = 0.0_pReal - call kinetics_slip(Mp,T,ph,me,dot_gamma_sl,ddot_gamma_dtau_slip) + call kinetics_slip(Mp,T,ph,en,dot_gamma_sl,ddot_gamma_dtau_slip) slipContribution: do i = 1, prm%sum_N_sl Lp = Lp + dot_gamma_sl(i)*prm%P_sl(1:3,1:3,i) forall (k=1:3,l=1:3,m=1:3,n=1:3) & @@ -579,7 +579,7 @@ module subroutine dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,ph,me) + ddot_gamma_dtau_slip(i) * prm%P_sl(k,l,i) * prm%P_sl(m,n,i) enddo slipContribution - call kinetics_twin(Mp,T,dot_gamma_sl,ph,me,dot_gamma_tw,ddot_gamma_dtau_tw) + call kinetics_twin(Mp,T,dot_gamma_sl,ph,en,dot_gamma_tw,ddot_gamma_dtau_tw) twinContibution: do i = 1, prm%sum_N_tw Lp = Lp + dot_gamma_tw(i)*prm%P_tw(1:3,1:3,i) forall (k=1:3,l=1:3,m=1:3,n=1:3) & @@ -587,7 +587,7 @@ module subroutine dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,ph,me) + ddot_gamma_dtau_tw(i)* prm%P_tw(k,l,i)*prm%P_tw(m,n,i) enddo twinContibution - call kinetics_trans(Mp,T,dot_gamma_sl,ph,me,dot_gamma_tr,ddot_gamma_dtau_tr) + call kinetics_trans(Mp,T,dot_gamma_sl,ph,en,dot_gamma_tr,ddot_gamma_dtau_tr) transContibution: do i = 1, prm%sum_N_tr Lp = Lp + dot_gamma_tr(i)*prm%P_tr(1:3,1:3,i) forall (k=1:3,l=1:3,m=1:3,n=1:3) & @@ -632,7 +632,7 @@ end subroutine dislotwin_LpAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief Calculate the rate of change of microstructure. !-------------------------------------------------------------------------------------------------- -module subroutine dislotwin_dotState(Mp,T,ph,me) +module subroutine dislotwin_dotState(Mp,T,ph,en) real(pReal), dimension(3,3), intent(in):: & Mp !< Mandel stress @@ -640,7 +640,7 @@ module subroutine dislotwin_dotState(Mp,T,ph,me) T !< temperature at integration point integer, intent(in) :: & ph, & - me + en integer :: i real(pReal) :: & @@ -664,11 +664,11 @@ module subroutine dislotwin_dotState(Mp,T,ph,me) dot => dotState(ph), dst => dependentState(ph)) f_unrotated = 1.0_pReal & - - sum(stt%f_tw(1:prm%sum_N_tw,me)) & - - sum(stt%f_tr(1:prm%sum_N_tr,me)) + - sum(stt%f_tw(1:prm%sum_N_tw,en)) & + - sum(stt%f_tr(1:prm%sum_N_tr,en)) - call kinetics_slip(Mp,T,ph,me,dot_gamma_sl) - dot%gamma_sl(:,me) = abs(dot_gamma_sl) + call kinetics_slip(Mp,T,ph,en,dot_gamma_sl) + dot%gamma_sl(:,en) = abs(dot_gamma_sl) rho_dip_distance_min = prm%D_a*prm%b_sl @@ -680,11 +680,11 @@ module subroutine dislotwin_dotState(Mp,T,ph,me) dot_rho_dip_climb(i) = 0.0_pReal else significantSlipStress rho_dip_distance = 3.0_pReal*prm%mu*prm%b_sl(i)/(16.0_pReal*PI*abs(tau)) - rho_dip_distance = math_clip(rho_dip_distance, right = dst%Lambda_sl(i,me)) + rho_dip_distance = math_clip(rho_dip_distance, right = dst%Lambda_sl(i,en)) rho_dip_distance = math_clip(rho_dip_distance, left = rho_dip_distance_min(i)) dot_rho_dip_formation(i) = 2.0_pReal*(rho_dip_distance-rho_dip_distance_min(i))/prm%b_sl(i) & - * stt%rho_mob(i,me)*abs(dot_gamma_sl(i)) + * stt%rho_mob(i,en)*abs(dot_gamma_sl(i)) if (dEq(rho_dip_distance,rho_dip_distance_min(i))) then dot_rho_dip_climb(i) = 0.0_pReal @@ -698,25 +698,25 @@ module subroutine dislotwin_dotState(Mp,T,ph,me) v_cl = 2.0_pReal*prm%omega*b_d**2.0_pReal*exp(-prm%Q_cl/(kB*T)) & * (exp(abs(sigma_cl)*prm%b_sl(i)**3.0_pReal/(kB*T)) - 1.0_pReal) - dot_rho_dip_climb(i) = 4.0_pReal*v_cl*stt%rho_dip(i,me) & + dot_rho_dip_climb(i) = 4.0_pReal*v_cl*stt%rho_dip(i,en) & / (rho_dip_distance-rho_dip_distance_min(i)) endif endif significantSlipStress enddo slipState - dot%rho_mob(:,me) = abs(dot_gamma_sl)/(prm%b_sl*dst%Lambda_sl(:,me)) & + dot%rho_mob(:,en) = abs(dot_gamma_sl)/(prm%b_sl*dst%Lambda_sl(:,en)) & - dot_rho_dip_formation & - - 2.0_pReal*rho_dip_distance_min/prm%b_sl * stt%rho_mob(:,me)*abs(dot_gamma_sl) + - 2.0_pReal*rho_dip_distance_min/prm%b_sl * stt%rho_mob(:,en)*abs(dot_gamma_sl) - dot%rho_dip(:,me) = dot_rho_dip_formation & - - 2.0_pReal*rho_dip_distance_min/prm%b_sl * stt%rho_dip(:,me)*abs(dot_gamma_sl) & + dot%rho_dip(:,en) = dot_rho_dip_formation & + - 2.0_pReal*rho_dip_distance_min/prm%b_sl * stt%rho_dip(:,en)*abs(dot_gamma_sl) & - dot_rho_dip_climb - call kinetics_twin(Mp,T,dot_gamma_sl,ph,me,dot_gamma_tw) - dot%f_tw(:,me) = f_unrotated*dot_gamma_tw/prm%gamma_char + call kinetics_twin(Mp,T,dot_gamma_sl,ph,en,dot_gamma_tw) + dot%f_tw(:,en) = f_unrotated*dot_gamma_tw/prm%gamma_char - call kinetics_trans(Mp,T,dot_gamma_sl,ph,me,dot_gamma_tr) - dot%f_tr(:,me) = f_unrotated*dot_gamma_tr + call kinetics_trans(Mp,T,dot_gamma_sl,ph,en,dot_gamma_tr) + dot%f_tr(:,en) = f_unrotated*dot_gamma_tr end associate @@ -726,11 +726,11 @@ end subroutine dislotwin_dotState !-------------------------------------------------------------------------------------------------- !> @brief Calculate derived quantities from state. !-------------------------------------------------------------------------------------------------- -module subroutine dislotwin_dependentState(T,ph,me) +module subroutine dislotwin_dependentState(T,ph,en) integer, intent(in) :: & ph, & - me + en real(pReal), intent(in) :: & T @@ -752,50 +752,50 @@ module subroutine dislotwin_dependentState(T,ph,me) stt => state(ph),& dst => dependentState(ph)) - sumf_tw = sum(stt%f_tw(1:prm%sum_N_tw,me)) - sumf_tr = sum(stt%f_tr(1:prm%sum_N_tr,me)) + sumf_tw = sum(stt%f_tw(1:prm%sum_N_tw,en)) + sumf_tr = sum(stt%f_tr(1:prm%sum_N_tr,en)) Gamma = prm%Gamma_sf_0K + prm%dGamma_sf_dT * T !* rescaled volume fraction for topology - f_over_t_tw = stt%f_tw(1:prm%sum_N_tw,me)/prm%t_tw ! this is per system ... + f_over_t_tw = stt%f_tw(1:prm%sum_N_tw,en)/prm%t_tw ! this is per system ... f_over_t_tr = sumf_tr/prm%t_tr ! but this not ! ToDo ...Physically correct, but naming could be adjusted - inv_lambda_sl = sqrt(matmul(prm%forestProjection,stt%rho_mob(:,me)+stt%rho_dip(:,me)))/prm%i_sl + inv_lambda_sl = sqrt(matmul(prm%forestProjection,stt%rho_mob(:,en)+stt%rho_dip(:,en)))/prm%i_sl if (prm%sum_N_tw > 0 .and. prm%sum_N_sl > 0) & inv_lambda_sl = inv_lambda_sl + matmul(prm%h_sl_tw,f_over_t_tw)/(1.0_pReal-sumf_tw) if (prm%sum_N_tr > 0 .and. prm%sum_N_sl > 0) & inv_lambda_sl = inv_lambda_sl + matmul(prm%h_sl_tr,f_over_t_tr)/(1.0_pReal-sumf_tr) - dst%Lambda_sl(:,me) = prm%D / (1.0_pReal+prm%D*inv_lambda_sl) + dst%Lambda_sl(:,en) = prm%D / (1.0_pReal+prm%D*inv_lambda_sl) inv_lambda_tw_tw = matmul(prm%h_tw_tw,f_over_t_tw)/(1.0_pReal-sumf_tw) - dst%Lambda_tw(:,me) = prm%i_tw*prm%D/(1.0_pReal+prm%D*inv_lambda_tw_tw) + dst%Lambda_tw(:,en) = prm%i_tw*prm%D/(1.0_pReal+prm%D*inv_lambda_tw_tw) inv_lambda_tr_tr = matmul(prm%h_tr_tr,f_over_t_tr)/(1.0_pReal-sumf_tr) - dst%Lambda_tr(:,me) = prm%i_tr*prm%D/(1.0_pReal+prm%D*inv_lambda_tr_tr) + dst%Lambda_tr(:,en) = prm%i_tr*prm%D/(1.0_pReal+prm%D*inv_lambda_tr_tr) !* threshold stress for dislocation motion - dst%tau_pass(:,me) = prm%mu*prm%b_sl* sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,me)+stt%rho_dip(:,me))) + dst%tau_pass(:,en) = prm%mu*prm%b_sl* sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,en)+stt%rho_dip(:,en))) !* threshold stress for growing twin/martensite if(prm%sum_N_tw == prm%sum_N_sl) & - dst%tau_hat_tw(:,me) = Gamma/(3.0_pReal*prm%b_tw) & + dst%tau_hat_tw(:,en) = Gamma/(3.0_pReal*prm%b_tw) & + 3.0_pReal*prm%b_tw*prm%mu/(prm%L_tw*prm%b_sl) ! slip Burgers here correct? if(prm%sum_N_tr == prm%sum_N_sl) & - dst%tau_hat_tr(:,me) = Gamma/(3.0_pReal*prm%b_tr) & + dst%tau_hat_tr(:,en) = Gamma/(3.0_pReal*prm%b_tr) & + 3.0_pReal*prm%b_tr*prm%mu/(prm%L_tr*prm%b_sl) & ! slip Burgers here correct? + prm%h*prm%delta_G/ (3.0_pReal*prm%b_tr) - dst%V_tw(:,me) = (PI/4.0_pReal)*prm%t_tw*dst%Lambda_tw(:,me)**2.0_pReal - dst%V_tr(:,me) = (PI/4.0_pReal)*prm%t_tr*dst%Lambda_tr(:,me)**2.0_pReal + dst%V_tw(:,en) = (PI/4.0_pReal)*prm%t_tw*dst%Lambda_tw(:,en)**2.0_pReal + dst%V_tr(:,en) = (PI/4.0_pReal)*prm%t_tr*dst%Lambda_tr(:,en)**2.0_pReal x0 = prm%mu*prm%b_tw**2.0_pReal/(Gamma*8.0_pReal*PI)*(2.0_pReal+prm%nu)/(1.0_pReal-prm%nu) ! ToDo: In the paper, this is the Burgers vector for slip and is the same for twin and trans - dst%tau_r_tw(:,me) = prm%mu*prm%b_tw/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%x_c_tw)+cos(pi/3.0_pReal)/x0) + dst%tau_r_tw(:,en) = prm%mu*prm%b_tw/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%x_c_tw)+cos(pi/3.0_pReal)/x0) x0 = prm%mu*prm%b_tr**2.0_pReal/(Gamma*8.0_pReal*PI)*(2.0_pReal+prm%nu)/(1.0_pReal-prm%nu) ! ToDo: In the paper, this is the Burgers vector for slip - dst%tau_r_tr(:,me) = prm%mu*prm%b_tr/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%x_c_tr)+cos(pi/3.0_pReal)/x0) + dst%tau_r_tr(:,en) = prm%mu*prm%b_tr/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%x_c_tr)+cos(pi/3.0_pReal)/x0) end associate @@ -860,7 +860,7 @@ end subroutine plastic_dislotwin_results ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end !-------------------------------------------------------------------------------------------------- -pure subroutine kinetics_slip(Mp,T,ph,me, & +pure subroutine kinetics_slip(Mp,T,ph,en, & dot_gamma_sl,ddot_gamma_dtau_slip,tau_slip) real(pReal), dimension(3,3), intent(in) :: & @@ -869,7 +869,7 @@ pure subroutine kinetics_slip(Mp,T,ph,me, & T !< temperature integer, intent(in) :: & ph, & - me + en real(pReal), dimension(param(ph)%sum_N_sl), intent(out) :: & dot_gamma_sl @@ -898,7 +898,7 @@ pure subroutine kinetics_slip(Mp,T,ph,me, & tau(i) = math_tensordot(Mp,prm%P_sl(1:3,1:3,i)) enddo - tau_eff = abs(tau)-dst%tau_pass(:,me) + tau_eff = abs(tau)-dst%tau_pass(:,en) significantStress: where(tau_eff > tol_math_check) stressRatio = tau_eff/prm%tau_0 @@ -907,7 +907,7 @@ pure subroutine kinetics_slip(Mp,T,ph,me, & v_wait_inverse = prm%v_0**(-1.0_pReal) * exp(BoltzmannRatio*(1.0_pReal-StressRatio_p)** prm%q) v_run_inverse = prm%B/(tau_eff*prm%b_sl) - dot_gamma_sl = sign(stt%rho_mob(:,me)*prm%b_sl/(v_wait_inverse+v_run_inverse),tau) + dot_gamma_sl = sign(stt%rho_mob(:,en)*prm%b_sl/(v_wait_inverse+v_run_inverse),tau) dV_wait_inverse_dTau = -1.0_pReal * v_wait_inverse * prm%p * prm%q * BoltzmannRatio & * (stressRatio**(prm%p-1.0_pReal)) & @@ -916,7 +916,7 @@ pure subroutine kinetics_slip(Mp,T,ph,me, & dV_run_inverse_dTau = -1.0_pReal * v_run_inverse/tau_eff dV_dTau = -1.0_pReal * (dV_wait_inverse_dTau+dV_run_inverse_dTau) & / (v_wait_inverse+v_run_inverse)**2.0_pReal - ddot_gamma_dtau = dV_dTau*stt%rho_mob(:,me)*prm%b_sl + ddot_gamma_dtau = dV_dTau*stt%rho_mob(:,en)*prm%b_sl else where significantStress dot_gamma_sl = 0.0_pReal ddot_gamma_dtau = 0.0_pReal @@ -937,7 +937,7 @@ end subroutine kinetics_slip ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end. !-------------------------------------------------------------------------------------------------- -pure subroutine kinetics_twin(Mp,T,dot_gamma_sl,ph,me,& +pure subroutine kinetics_twin(Mp,T,dot_gamma_sl,ph,en,& dot_gamma_tw,ddot_gamma_dtau_tw) real(pReal), dimension(3,3), intent(in) :: & @@ -946,7 +946,7 @@ pure subroutine kinetics_twin(Mp,T,dot_gamma_sl,ph,me,& T !< temperature integer, intent(in) :: & ph, & - me + en real(pReal), dimension(param(ph)%sum_N_sl), intent(in) :: & dot_gamma_sl @@ -970,11 +970,11 @@ pure subroutine kinetics_twin(Mp,T,dot_gamma_sl,ph,me,& isFCC: if (prm%fccTwinTransNucleation) then s1=prm%fcc_twinNucleationSlipPair(1,i) s2=prm%fcc_twinNucleationSlipPair(2,i) - if (tau(i) < dst%tau_r_tw(i,me)) then ! ToDo: correct? - Ndot0=(abs(dot_gamma_sl(s1))*(stt%rho_mob(s2,me)+stt%rho_dip(s2,me))+& - abs(dot_gamma_sl(s2))*(stt%rho_mob(s1,me)+stt%rho_dip(s1,me)))/& ! ToDo: MD: it would be more consistent to use shearrates from state + if (tau(i) < dst%tau_r_tw(i,en)) then ! ToDo: correct? + Ndot0=(abs(dot_gamma_sl(s1))*(stt%rho_mob(s2,en)+stt%rho_dip(s2,en))+& + abs(dot_gamma_sl(s2))*(stt%rho_mob(s1,en)+stt%rho_dip(s1,en)))/& ! ToDo: MD: it would be more consistent to use shearrates from state (prm%L_tw*prm%b_sl(i))*& - (1.0_pReal-exp(-prm%V_cs/(kB*T)*(dst%tau_r_tw(i,me)-tau(i)))) ! P_ncs + (1.0_pReal-exp(-prm%V_cs/(kB*T)*(dst%tau_r_tw(i,en)-tau(i)))) ! P_ncs else Ndot0=0.0_pReal end if @@ -984,8 +984,8 @@ pure subroutine kinetics_twin(Mp,T,dot_gamma_sl,ph,me,& enddo significantStress: where(tau > tol_math_check) - StressRatio_r = (dst%tau_hat_tw(:,me)/tau)**prm%r - dot_gamma_tw = prm%gamma_char * dst%V_tw(:,me) * Ndot0*exp(-StressRatio_r) + StressRatio_r = (dst%tau_hat_tw(:,en)/tau)**prm%r + dot_gamma_tw = prm%gamma_char * dst%V_tw(:,en) * Ndot0*exp(-StressRatio_r) ddot_gamma_dtau = (dot_gamma_tw*prm%r/tau)*StressRatio_r else where significantStress dot_gamma_tw = 0.0_pReal @@ -1006,7 +1006,7 @@ end subroutine kinetics_twin ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end. !-------------------------------------------------------------------------------------------------- -pure subroutine kinetics_trans(Mp,T,dot_gamma_sl,ph,me,& +pure subroutine kinetics_trans(Mp,T,dot_gamma_sl,ph,en,& dot_gamma_tr,ddot_gamma_dtau_tr) real(pReal), dimension(3,3), intent(in) :: & @@ -1015,7 +1015,7 @@ pure subroutine kinetics_trans(Mp,T,dot_gamma_sl,ph,me,& T !< temperature integer, intent(in) :: & ph, & - me + en real(pReal), dimension(param(ph)%sum_N_sl), intent(in) :: & dot_gamma_sl @@ -1038,11 +1038,11 @@ pure subroutine kinetics_trans(Mp,T,dot_gamma_sl,ph,me,& isFCC: if (prm%fccTwinTransNucleation) then s1=prm%fcc_twinNucleationSlipPair(1,i) s2=prm%fcc_twinNucleationSlipPair(2,i) - if (tau(i) < dst%tau_r_tr(i,me)) then ! ToDo: correct? - Ndot0=(abs(dot_gamma_sl(s1))*(stt%rho_mob(s2,me)+stt%rho_dip(s2,me))+& - abs(dot_gamma_sl(s2))*(stt%rho_mob(s1,me)+stt%rho_dip(s1,me)))/& ! ToDo: MD: it would be more consistent to use shearrates from state + if (tau(i) < dst%tau_r_tr(i,en)) then ! ToDo: correct? + Ndot0=(abs(dot_gamma_sl(s1))*(stt%rho_mob(s2,en)+stt%rho_dip(s2,en))+& + abs(dot_gamma_sl(s2))*(stt%rho_mob(s1,en)+stt%rho_dip(s1,en)))/& ! ToDo: MD: it would be more consistent to use shearrates from state (prm%L_tr*prm%b_sl(i))*& - (1.0_pReal-exp(-prm%V_cs/(kB*T)*(dst%tau_r_tr(i,me)-tau(i)))) ! P_ncs + (1.0_pReal-exp(-prm%V_cs/(kB*T)*(dst%tau_r_tr(i,en)-tau(i)))) ! P_ncs else Ndot0=0.0_pReal end if @@ -1052,8 +1052,8 @@ pure subroutine kinetics_trans(Mp,T,dot_gamma_sl,ph,me,& enddo significantStress: where(tau > tol_math_check) - StressRatio_s = (dst%tau_hat_tr(:,me)/tau)**prm%s - dot_gamma_tr = dst%V_tr(:,me) * Ndot0*exp(-StressRatio_s) + StressRatio_s = (dst%tau_hat_tr(:,en)/tau)**prm%s + dot_gamma_tr = dst%V_tr(:,en) * Ndot0*exp(-StressRatio_s) ddot_gamma_dtau = (dot_gamma_tr*prm%s/tau)*StressRatio_s else where significantStress dot_gamma_tr = 0.0_pReal diff --git a/src/phase_mechanical_plastic_isotropic.f90 b/src/phase_mechanical_plastic_isotropic.f90 index d1f191f28..5ab73895f 100644 --- a/src/phase_mechanical_plastic_isotropic.f90 +++ b/src/phase_mechanical_plastic_isotropic.f90 @@ -156,7 +156,7 @@ end function plastic_isotropic_init !-------------------------------------------------------------------------------------------------- !> @brief Calculate plastic velocity gradient and its tangent. !-------------------------------------------------------------------------------------------------- -module subroutine isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) +module subroutine isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en) real(pReal), dimension(3,3), intent(out) :: & Lp !< plastic velocity gradient @@ -167,7 +167,7 @@ module subroutine isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) Mp !< Mandel stress integer, intent(in) :: & ph, & - me + en real(pReal), dimension(3,3) :: & Mp_dev !< deviatoric part of the Mandel stress @@ -185,7 +185,7 @@ module subroutine isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) norm_Mp_dev = sqrt(squarenorm_Mp_dev) if (norm_Mp_dev > 0.0_pReal) then - dot_gamma = prm%dot_gamma_0 * (sqrt(1.5_pReal) * norm_Mp_dev/(prm%M*stt%xi(me))) **prm%n + dot_gamma = prm%dot_gamma_0 * (sqrt(1.5_pReal) * norm_Mp_dev/(prm%M*stt%xi(en))) **prm%n Lp = dot_gamma/prm%M * Mp_dev/norm_Mp_dev forall (k=1:3,l=1:3,m=1:3,n=1:3) & @@ -248,13 +248,13 @@ module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,ph,en) !-------------------------------------------------------------------------------------------------- !> @brief Calculate the rate of change of microstructure. !-------------------------------------------------------------------------------------------------- -module subroutine isotropic_dotState(Mp,ph,me) +module subroutine isotropic_dotState(Mp,ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress integer, intent(in) :: & ph, & - me + en real(pReal) :: & dot_gamma, & !< strainrate @@ -270,7 +270,7 @@ module subroutine isotropic_dotState(Mp,ph,me) norm_Mp = sqrt(math_tensordot(math_deviatoric33(Mp),math_deviatoric33(Mp))) endif - dot_gamma = prm%dot_gamma_0 * (sqrt(1.5_pReal) * norm_Mp /(prm%M*stt%xi(me))) **prm%n + dot_gamma = prm%dot_gamma_0 * (sqrt(1.5_pReal) * norm_Mp /(prm%M*stt%xi(en))) **prm%n if (dot_gamma > 1e-12_pReal) then if (dEq0(prm%c_1)) then @@ -280,15 +280,15 @@ module subroutine isotropic_dotState(Mp,ph,me) + asinh( (dot_gamma / prm%c_1)**(1.0_pReal / prm%c_2))**(1.0_pReal / prm%c_3) & / prm%c_4 * (dot_gamma / prm%dot_gamma_0)**(1.0_pReal / prm%n) endif - dot%xi(me) = dot_gamma & + dot%xi(en) = dot_gamma & * ( prm%h_0 + prm%h_ln * log(dot_gamma) ) & - * abs( 1.0_pReal - stt%xi(me)/xi_inf_star )**prm%a & - * sign(1.0_pReal, 1.0_pReal - stt%xi(me)/xi_inf_star) + * abs( 1.0_pReal - stt%xi(en)/xi_inf_star )**prm%a & + * sign(1.0_pReal, 1.0_pReal - stt%xi(en)/xi_inf_star) else - dot%xi(me) = 0.0_pReal + dot%xi(en) = 0.0_pReal endif - dot%gamma(me) = dot_gamma ! ToDo: not really used + dot%gamma(en) = dot_gamma ! ToDo: not really used end associate diff --git a/src/phase_mechanical_plastic_kinehardening.f90 b/src/phase_mechanical_plastic_kinehardening.f90 index 936a7f884..7acfd2675 100644 --- a/src/phase_mechanical_plastic_kinehardening.f90 +++ b/src/phase_mechanical_plastic_kinehardening.f90 @@ -230,7 +230,7 @@ end function plastic_kinehardening_init !-------------------------------------------------------------------------------------------------- !> @brief Calculate plastic velocity gradient and its tangent. !-------------------------------------------------------------------------------------------------- -pure module subroutine kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) +pure module subroutine kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en) real(pReal), dimension(3,3), intent(out) :: & Lp !< plastic velocity gradient @@ -241,7 +241,7 @@ pure module subroutine kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) Mp !< Mandel stress integer, intent(in) :: & ph, & - me + en integer :: & i,k,l,m,n @@ -254,7 +254,7 @@ pure module subroutine kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) associate(prm => param(ph)) - call kinetics(Mp,ph,me,gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg) + call kinetics(Mp,ph,en,gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg) do i = 1, prm%sum_N_sl Lp = Lp + (gdot_pos(i)+gdot_neg(i))*prm%P(1:3,1:3,i) @@ -272,13 +272,13 @@ end subroutine kinehardening_LpAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief Calculate the rate of change of microstructure. !-------------------------------------------------------------------------------------------------- -module subroutine plastic_kinehardening_dotState(Mp,ph,me) +module subroutine plastic_kinehardening_dotState(Mp,ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress integer, intent(in) :: & ph, & - me + en real(pReal) :: & sumGamma @@ -289,22 +289,22 @@ module subroutine plastic_kinehardening_dotState(Mp,ph,me) associate(prm => param(ph), stt => state(ph),& dot => dotState(ph)) - call kinetics(Mp,ph,me,gdot_pos,gdot_neg) - dot%accshear(:,me) = abs(gdot_pos+gdot_neg) - sumGamma = sum(stt%accshear(:,me)) + call kinetics(Mp,ph,en,gdot_pos,gdot_neg) + dot%accshear(:,en) = abs(gdot_pos+gdot_neg) + sumGamma = sum(stt%accshear(:,en)) - dot%crss(:,me) = matmul(prm%interaction_SlipSlip,dot%accshear(:,me)) & + dot%crss(:,en) = matmul(prm%interaction_SlipSlip,dot%accshear(:,en)) & * ( prm%h_inf_f & + (prm%h_0_f - prm%h_inf_f + prm%h_0_f*prm%h_inf_f*sumGamma/prm%xi_inf_f) & * exp(-sumGamma*prm%h_0_f/prm%xi_inf_f) & ) - dot%crss_back(:,me) = stt%sense(:,me)*dot%accshear(:,me) * & + dot%crss_back(:,en) = stt%sense(:,en)*dot%accshear(:,en) * & ( prm%h_inf_b + & (prm%h_0_b - prm%h_inf_b & - + prm%h_0_b*prm%h_inf_b/(prm%xi_inf_b+stt%chi0(:,me))*(stt%accshear(:,me)-stt%gamma0(:,me))& - ) *exp(-(stt%accshear(:,me)-stt%gamma0(:,me)) *prm%h_0_b/(prm%xi_inf_b+stt%chi0(:,me))) & + + prm%h_0_b*prm%h_inf_b/(prm%xi_inf_b+stt%chi0(:,en))*(stt%accshear(:,en)-stt%gamma0(:,en))& + ) *exp(-(stt%accshear(:,en)-stt%gamma0(:,en)) *prm%h_0_b/(prm%xi_inf_b+stt%chi0(:,en))) & ) end associate @@ -315,13 +315,13 @@ end subroutine plastic_kinehardening_dotState !-------------------------------------------------------------------------------------------------- !> @brief Calculate (instantaneous) incremental change of microstructure. !-------------------------------------------------------------------------------------------------- -module subroutine plastic_kinehardening_deltaState(Mp,ph,me) +module subroutine plastic_kinehardening_deltaState(Mp,ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress integer, intent(in) :: & ph, & - me + en real(pReal), dimension(param(ph)%sum_N_sl) :: & gdot_pos,gdot_neg, & @@ -329,22 +329,22 @@ module subroutine plastic_kinehardening_deltaState(Mp,ph,me) associate(prm => param(ph), stt => state(ph), dlt => deltaState(ph)) - call kinetics(Mp,ph,me,gdot_pos,gdot_neg) - sense = merge(state(ph)%sense(:,me), & ! keep existing... + call kinetics(Mp,ph,en,gdot_pos,gdot_neg) + sense = merge(state(ph)%sense(:,en), & ! keep existing... sign(1.0_pReal,gdot_pos+gdot_neg), & ! ...or have a defined dEq0(gdot_pos+gdot_neg,1e-10_pReal)) ! current sense of shear direction !-------------------------------------------------------------------------------------------------- -! switch in sense me shear? - where(dNeq(sense,stt%sense(:,me),0.1_pReal)) - dlt%sense (:,me) = sense - stt%sense(:,me) ! switch sense - dlt%chi0 (:,me) = abs(stt%crss_back(:,me)) - stt%chi0(:,me) ! remember current backstress magnitude - dlt%gamma0(:,me) = stt%accshear(:,me) - stt%gamma0(:,me) ! remember current accumulated shear +! switch in sense en shear? + where(dNeq(sense,stt%sense(:,en),0.1_pReal)) + dlt%sense (:,en) = sense - stt%sense(:,en) ! switch sense + dlt%chi0 (:,en) = abs(stt%crss_back(:,en)) - stt%chi0(:,en) ! remember current backstress magnitude + dlt%gamma0(:,en) = stt%accshear(:,en) - stt%gamma0(:,en) ! remember current accumulated shear else where - dlt%sense (:,me) = 0.0_pReal - dlt%chi0 (:,me) = 0.0_pReal - dlt%gamma0(:,me) = 0.0_pReal + dlt%sense (:,en) = 0.0_pReal + dlt%chi0 (:,en) = 0.0_pReal + dlt%gamma0(:,en) = 0.0_pReal end where end associate @@ -397,14 +397,14 @@ end subroutine plastic_kinehardening_results ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end. !-------------------------------------------------------------------------------------------------- -pure subroutine kinetics(Mp,ph,me, & +pure subroutine kinetics(Mp,ph,en, & gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress integer, intent(in) :: & ph, & - me + en real(pReal), intent(out), dimension(param(ph)%sum_N_sl) :: & gdot_pos, & @@ -421,21 +421,21 @@ pure subroutine kinetics(Mp,ph,me, & associate(prm => param(ph), stt => state(ph)) do i = 1, prm%sum_N_sl - tau_pos(i) = math_tensordot(Mp,prm%nonSchmid_pos(1:3,1:3,i)) - stt%crss_back(i,me) - tau_neg(i) = merge(math_tensordot(Mp,prm%nonSchmid_neg(1:3,1:3,i)) - stt%crss_back(i,me), & + tau_pos(i) = math_tensordot(Mp,prm%nonSchmid_pos(1:3,1:3,i)) - stt%crss_back(i,en) + tau_neg(i) = merge(math_tensordot(Mp,prm%nonSchmid_neg(1:3,1:3,i)) - stt%crss_back(i,en), & 0.0_pReal, prm%nonSchmidActive) enddo where(dNeq0(tau_pos)) gdot_pos = prm%dot_gamma_0 * merge(0.5_pReal,1.0_pReal, prm%nonSchmidActive) & ! 1/2 if non-Schmid active - * sign(abs(tau_pos/stt%crss(:,me))**prm%n, tau_pos) + * sign(abs(tau_pos/stt%crss(:,en))**prm%n, tau_pos) else where gdot_pos = 0.0_pReal end where where(dNeq0(tau_neg)) gdot_neg = prm%dot_gamma_0 * 0.5_pReal & ! only used if non-Schmid active, always 1/2 - * sign(abs(tau_neg/stt%crss(:,me))**prm%n, tau_neg) + * sign(abs(tau_neg/stt%crss(:,en))**prm%n, tau_neg) else where gdot_neg = 0.0_pReal end where diff --git a/src/phase_mechanical_plastic_nonlocal.f90 b/src/phase_mechanical_plastic_nonlocal.f90 index ba7f76881..cf34597b6 100644 --- a/src/phase_mechanical_plastic_nonlocal.f90 +++ b/src/phase_mechanical_plastic_nonlocal.f90 @@ -49,7 +49,7 @@ submodule(phase:plastic) nonlocal !END DEPRECATED real(pReal), dimension(:,:,:,:,:,:), allocatable :: & - compatibility !< slip system compatibility between me and my neighbors + compatibility !< slip system compatibility between en and my neighbors type :: tInitialParameters !< container type for internal constitutive parameters real(pReal) :: & @@ -558,11 +558,11 @@ end function plastic_nonlocal_init !-------------------------------------------------------------------------------------------------- !> @brief calculates quantities characterizing the microstructure !-------------------------------------------------------------------------------------------------- -module subroutine nonlocal_dependentState(ph, me, ip, el) +module subroutine nonlocal_dependentState(ph, en, ip, el) integer, intent(in) :: & ph, & - me, & + en, & ip, & el @@ -615,9 +615,9 @@ module subroutine nonlocal_dependentState(ph, me, ip, el) associate(prm => param(ph),dst => microstructure(ph), stt => state(ph)) - rho = getRho(ph,me) + rho = getRho(ph,en) - stt%rho_forest(:,me) = matmul(prm%forestProjection_Edge, sum(abs(rho(:,edg)),2)) & + stt%rho_forest(:,en) = matmul(prm%forestProjection_Edge, sum(abs(rho(:,edg)),2)) & + matmul(prm%forestProjection_Screw,sum(abs(rho(:,scr)),2)) @@ -627,13 +627,13 @@ module subroutine nonlocal_dependentState(ph, me, ip, el) myInteractionMatrix = prm%h_sl_sl & * spread(( 1.0_pReal - prm%f_F & + prm%f_F & - * log(0.35_pReal * prm%b_sl * sqrt(max(stt%rho_forest(:,me),prm%rho_significant))) & + * log(0.35_pReal * prm%b_sl * sqrt(max(stt%rho_forest(:,en),prm%rho_significant))) & / log(0.35_pReal * prm%b_sl * 1e6_pReal))** 2.0_pReal,2,prm%sum_N_sl) else myInteractionMatrix = prm%h_sl_sl endif - dst%tau_pass(:,me) = prm%mu * prm%b_sl & + dst%tau_pass(:,en) = prm%mu * prm%b_sl & * sqrt(matmul(myInteractionMatrix,sum(abs(rho),2))) !*** calculate the dislocation stress of the neighboring excess dislocation densities @@ -643,10 +643,10 @@ module subroutine nonlocal_dependentState(ph, me, ip, el) ! ToDo: MD: this is most likely only correct for F_i = I !################################################################################################# - rho0 = getRho0(ph,me) + rho0 = getRho0(ph,en) if (.not. phase_localPlasticity(material_phaseAt(1,el)) .and. prm%shortRangeStressCorrection) then - invFp = math_inv33(phase_mechanical_Fp(ph)%data(1:3,1:3,me)) - invFe = math_inv33(phase_mechanical_Fe(ph)%data(1:3,1:3,me)) + invFp = math_inv33(phase_mechanical_Fp(ph)%data(1:3,1:3,en)) + invFe = math_inv33(phase_mechanical_Fe(ph)%data(1:3,1:3,en)) rho_edg_delta = rho0(:,mob_edg_pos) - rho0(:,mob_edg_neg) rho_scr_delta = rho0(:,mob_scr_pos) - rho0(:,mob_scr_neg) @@ -654,7 +654,7 @@ module subroutine nonlocal_dependentState(ph, me, ip, el) rhoExcess(1,:) = rho_edg_delta rhoExcess(2,:) = rho_scr_delta - FVsize = geom(ph)%V_0(me) ** (1.0_pReal/3.0_pReal) + FVsize = geom(ph)%V_0(en) ** (1.0_pReal/3.0_pReal) !* loop through my neighborhood and get the connection vectors (in lattice frame) and the excess densities @@ -734,7 +734,7 @@ module subroutine nonlocal_dependentState(ph, me, ip, el) where(rhoTotal > 0.0_pReal) rhoExcessGradient_over_rho = rhoExcessGradient / rhoTotal ! ... gives the local stress correction when multiplied with a factor - dst%tau_back(s,me) = - prm%mu * prm%b_sl(s) / (2.0_pReal * PI) & + dst%tau_back(s,en) = - prm%mu * prm%b_sl(s) / (2.0_pReal * PI) & * ( rhoExcessGradient_over_rho(1) / (1.0_pReal - prm%nu) & + rhoExcessGradient_over_rho(2)) enddo @@ -745,9 +745,9 @@ module subroutine nonlocal_dependentState(ph, me, ip, el) .and. ((debugConstitutive%element == el .and. debugConstitutive%ip == ip)& .or. .not. debugConstitutive%selective)) then print'(/,a,i8,1x,i2,1x,i1,/)', '<< CONST >> nonlocal_microstructure at el ip ',el,ip - print'(a,/,12x,12(e10.3,1x))', '<< CONST >> rhoForest', stt%rho_forest(:,me) - print'(a,/,12x,12(f10.5,1x))', '<< CONST >> tauThreshold / MPa', dst%tau_pass(:,me)*1e-6 - print'(a,/,12x,12(f10.5,1x),/)', '<< CONST >> tauBack / MPa', dst%tau_back(:,me)*1e-6 + print'(a,/,12x,12(e10.3,1x))', '<< CONST >> rhoForest', stt%rho_forest(:,en) + print'(a,/,12x,12(f10.5,1x))', '<< CONST >> tauThreshold / MPa', dst%tau_pass(:,en)*1e-6 + print'(a,/,12x,12(f10.5,1x),/)', '<< CONST >> tauBack / MPa', dst%tau_back(:,en)*1e-6 endif #endif @@ -760,14 +760,14 @@ end subroutine nonlocal_dependentState !> @brief calculates plastic velocity gradient and its tangent !-------------------------------------------------------------------------------------------------- module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, & - Mp,Temperature,ph,me) + Mp,Temperature,ph,en) real(pReal), dimension(3,3), intent(out) :: & Lp !< plastic velocity gradient real(pReal), dimension(3,3,3,3), intent(out) :: & dLp_dMp integer, intent(in) :: & ph, & - me + en real(pReal), intent(in) :: & Temperature !< temperature @@ -800,7 +800,7 @@ module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, & ns = prm%sum_N_sl !*** shortcut to state variables - rho = getRho(ph,me) + rho = getRho(ph,en) rhoSgl = rho(:,sgl) do s = 1,ns @@ -815,12 +815,12 @@ module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, & tauNS(s,4) = math_tensordot(Mp, -prm%nonSchmid_pos(1:3,1:3,s)) endif enddo - tauNS = tauNS + spread(dst%tau_back(:,me),2,4) - tau = tau + dst%tau_back(:,me) + tauNS = tauNS + spread(dst%tau_back(:,en),2,4) + tau = tau + dst%tau_back(:,en) ! edges call kinetics(v(:,1), dv_dtau(:,1), dv_dtauNS(:,1), & - tau, tauNS(:,1), dst%tau_pass(:,me),1,Temperature, ph) + tau, tauNS(:,1), dst%tau_pass(:,en),1,Temperature, ph) v(:,2) = v(:,1) dv_dtau(:,2) = dv_dtau(:,1) dv_dtauNS(:,2) = dv_dtauNS(:,1) @@ -829,7 +829,7 @@ module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, & if (prm%nonSchmidActive) then do t = 3,4 call kinetics(v(:,t), dv_dtau(:,t), dv_dtauNS(:,t), & - tau, tauNS(:,t), dst%tau_pass(:,me),2,Temperature, ph) + tau, tauNS(:,t), dst%tau_pass(:,en),2,Temperature, ph) enddo else v(:,3:4) = spread(v(:,1),2,2) @@ -837,7 +837,7 @@ module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, & dv_dtauNS(:,3:4) = spread(dv_dtauNS(:,1),2,2) endif - stt%v(:,me) = pack(v,.true.) + stt%v(:,en) = pack(v,.true.) !*** Bauschinger effect forall (s = 1:ns, t = 5:8, rhoSgl(s,t) * v(s,t-4) < 0.0_pReal) & @@ -866,13 +866,13 @@ end subroutine nonlocal_LpAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief (instantaneous) incremental change of microstructure !-------------------------------------------------------------------------------------------------- -module subroutine plastic_nonlocal_deltaState(Mp,ph,me) +module subroutine plastic_nonlocal_deltaState(Mp,ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp !< MandelStress integer, intent(in) :: & ph, & - me + en integer :: & ns, & ! short notation for the total number of active slip systems @@ -898,10 +898,10 @@ module subroutine plastic_nonlocal_deltaState(Mp,ph,me) ns = prm%sum_N_sl !*** shortcut to state variables - forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,ph),me) - forall (s = 1:ns, c = 1:2) dUpperOld(s,c) = plasticState(ph)%state(iD(s,c,ph),me) + forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,ph),en) + forall (s = 1:ns, c = 1:2) dUpperOld(s,c) = plasticState(ph)%state(iD(s,c,ph),en) - rho = getRho(ph,me) + rho = getRho(ph,en) rhoDip = rho(:,dip) !**************************************************************************** @@ -922,7 +922,7 @@ module subroutine plastic_nonlocal_deltaState(Mp,ph,me) !*** calculate limits for stable dipole height do s = 1,prm%sum_N_sl - tau(s) = math_tensordot(Mp, prm%Schmid(1:3,1:3,s)) +dst%tau_back(s,me) + tau(s) = math_tensordot(Mp, prm%Schmid(1:3,1:3,s)) +dst%tau_back(s,en) if (abs(tau(s)) < 1.0e-15_pReal) tau(s) = 1.0e-15_pReal enddo @@ -946,10 +946,10 @@ module subroutine plastic_nonlocal_deltaState(Mp,ph,me) / (dUpperOld(s,c) - prm%minDipoleHeight(s,c)) forall (t=1:4) deltaRhoDipole2SingleStress(:,t) = -0.5_pReal * deltaRhoDipole2SingleStress(:,(t-1)/2+9) - forall (s = 1:ns, c = 1:2) plasticState(ph)%state(iD(s,c,ph),me) = dUpper(s,c) + forall (s = 1:ns, c = 1:2) plasticState(ph)%state(iD(s,c,ph),en) = dUpper(s,c) - plasticState(ph)%deltaState(:,me) = 0.0_pReal - del%rho(:,me) = reshape(deltaRhoRemobilization + deltaRhoDipole2SingleStress, [10*ns]) + plasticState(ph)%deltaState(:,en) = 0.0_pReal + del%rho(:,en) = reshape(deltaRhoRemobilization + deltaRhoDipole2SingleStress, [10*ns]) end associate @@ -960,7 +960,7 @@ end subroutine plastic_nonlocal_deltaState !> @brief calculates the rate of change of microstructure !--------------------------------------------------------------------------------------------------- module subroutine nonlocal_dotState(Mp, Temperature,timestep, & - ph,me,ip,el) + ph,en,ip,el) real(pReal), dimension(3,3), intent(in) :: & Mp !< MandelStress @@ -969,7 +969,7 @@ module subroutine nonlocal_dotState(Mp, Temperature,timestep, & timestep !< substepped crystallite time increment integer, intent(in) :: & ph, & - me, & + en, & ip, & !< current integration point el !< current element number @@ -1017,13 +1017,13 @@ module subroutine nonlocal_dotState(Mp, Temperature,timestep, & tau = 0.0_pReal gdot = 0.0_pReal - rho = getRho(ph,me) + rho = getRho(ph,en) rhoSgl = rho(:,sgl) rhoDip = rho(:,dip) - rho0 = getRho0(ph,me) + rho0 = getRho0(ph,en) my_rhoSgl0 = rho0(:,sgl) - forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,ph),me) + forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,ph),en) gdot = rhoSgl(:,1:4) * v * spread(prm%b_sl,2,4) #ifdef DEBUG @@ -1038,7 +1038,7 @@ module subroutine nonlocal_dotState(Mp, Temperature,timestep, & !**************************************************************************** !*** limits for stable dipole height do s = 1,ns - tau(s) = math_tensordot(Mp, prm%Schmid(1:3,1:3,s)) + dst%tau_back(s,me) + tau(s) = math_tensordot(Mp, prm%Schmid(1:3,1:3,s)) + dst%tau_back(s,en) if (abs(tau(s)) < 1.0e-15_pReal) tau(s) = 1.0e-15_pReal enddo @@ -1059,20 +1059,20 @@ module subroutine nonlocal_dotState(Mp, Temperature,timestep, & isBCC: if (lattice_structure(ph) == LATTICE_bcc_ID) then forall (s = 1:ns, sum(abs(v(s,1:4))) > 0.0_pReal) rhoDotMultiplication(s,1:2) = sum(abs(gdot(s,3:4))) / prm%b_sl(s) & ! assuming double-cross-slip of screws to be decisive for multiplication - * sqrt(stt%rho_forest(s,me)) / prm%i_sl(s) ! & ! mean free path + * sqrt(stt%rho_forest(s,en)) / prm%i_sl(s) ! & ! mean free path ! * 2.0_pReal * sum(abs(v(s,3:4))) / sum(abs(v(s,1:4))) ! ratio of screw to overall velocity determines edge generation rhoDotMultiplication(s,3:4) = sum(abs(gdot(s,3:4))) /prm%b_sl(s) & ! assuming double-cross-slip of screws to be decisive for multiplication - * sqrt(stt%rho_forest(s,me)) / prm%i_sl(s) ! & ! mean free path + * sqrt(stt%rho_forest(s,en)) / prm%i_sl(s) ! & ! mean free path ! * 2.0_pReal * sum(abs(v(s,1:2))) / sum(abs(v(s,1:4))) ! ratio of edge to overall velocity determines screw generation endforall else isBCC rhoDotMultiplication(:,1:4) = spread( & (sum(abs(gdot(:,1:2)),2) * prm%f_ed_mult + sum(abs(gdot(:,3:4)),2)) & - * sqrt(stt%rho_forest(:,me)) / prm%i_sl / prm%b_sl, 2, 4) + * sqrt(stt%rho_forest(:,en)) / prm%i_sl / prm%b_sl, 2, 4) endif isBCC - forall (s = 1:ns, t = 1:4) v0(s,t) = plasticState(ph)%state0(iV(s,t,ph),me) + forall (s = 1:ns, t = 1:4) v0(s,t) = plasticState(ph)%state0(iV(s,t,ph),en) !**************************************************************************** @@ -1115,10 +1115,10 @@ module subroutine nonlocal_dotState(Mp, Temperature,timestep, & if (lattice_structure(ph) == LATTICE_fcc_ID) & forall (s = 1:ns, prm%colinearSystem(s) > 0) & rhoDotAthermalAnnihilation(prm%colinearSystem(s),1:2) = - rhoDotAthermalAnnihilation(s,10) & - * 0.25_pReal * sqrt(stt%rho_forest(s,me)) * (dUpper(s,2) + dLower(s,2)) * prm%f_ed + * 0.25_pReal * sqrt(stt%rho_forest(s,en)) * (dUpper(s,2) + dLower(s,2)) * prm%f_ed - !*** thermally activated annihilation me edge dipoles by climb + !*** thermally activated annihilation en edge dipoles by climb rhoDotThermalAnnihilation = 0.0_pReal selfDiffusion = prm%D_0 * exp(-prm%Q_cl / (kB * Temperature)) vClimb = prm%V_at * selfDiffusion * prm%mu & @@ -1128,7 +1128,7 @@ module subroutine nonlocal_dotState(Mp, Temperature,timestep, & - rhoDip(s,1) / timestep - rhoDotAthermalAnnihilation(s,9) & - rhoDotSingle2DipoleGlide(s,9)) ! make sure that we do not annihilate more dipoles than we have - rhoDot = rhoDotFlux(timestep, ph,me,ip,el) & + rhoDot = rhoDotFlux(timestep, ph,en,ip,el) & + rhoDotMultiplication & + rhoDotSingle2DipoleGlide & + rhoDotAthermalAnnihilation & @@ -1145,8 +1145,8 @@ module subroutine nonlocal_dotState(Mp, Temperature,timestep, & #endif plasticState(ph)%dotState = IEEE_value(1.0_pReal,IEEE_quiet_NaN) else - dot%rho(:,me) = pack(rhoDot,.true.) - dot%gamma(:,me) = sum(gdot,2) + dot%rho(:,en) = pack(rhoDot,.true.) + dot%gamma(:,en) = sum(gdot,2) endif end associate @@ -1157,13 +1157,13 @@ end subroutine nonlocal_dotState !--------------------------------------------------------------------------------------------------- !> @brief calculates the rate of change of microstructure !--------------------------------------------------------------------------------------------------- -function rhoDotFlux(timestep,ph,me,ip,el) +function rhoDotFlux(timestep,ph,en,ip,el) real(pReal), intent(in) :: & timestep !< substepped crystallite time increment integer, intent(in) :: & ph, & - me, & + en, & ip, & !< current integration point el !< current element number @@ -1174,11 +1174,11 @@ function rhoDotFlux(timestep,ph,me,ip,el) n, & !< index of my current neighbor neighbor_el, & !< element number of my neighbor neighbor_ip, & !< integration point of my neighbor - neighbor_n, & !< neighbor index pointing to me when looking from my neighbor + neighbor_n, & !< neighbor index pointing to en when looking from my neighbor opposite_neighbor, & !< index of my opposite neighbor opposite_ip, & !< ip of my opposite neighbor opposite_el, & !< element index of my opposite neighbor - opposite_n, & !< neighbor index pointing to me when looking from my opposite neighbor + opposite_n, & !< neighbor index pointing to en when looking from my opposite neighbor t, & !< type of dislocation no,& !< neighbor offset shortcut np,& !< neighbor phase shortcut @@ -1204,12 +1204,12 @@ function rhoDotFlux(timestep,ph,me,ip,el) neighbor_F, & !< total deformation gradient of my neighbor my_Fe, & !< my elastic deformation gradient neighbor_Fe, & !< elastic deformation gradient of my neighbor - Favg !< average total deformation gradient of me and my neighbor + Favg !< average total deformation gradient of en and my neighbor real(pReal), dimension(3) :: & - normal_neighbor2me, & !< interface normal pointing from my neighbor to me in neighbor's lattice configuration - normal_neighbor2me_defConf, & !< interface normal pointing from my neighbor to me in shared deformed configuration - normal_me2neighbor, & !< interface normal pointing from me to my neighbor in my lattice configuration - normal_me2neighbor_defConf !< interface normal pointing from me to my neighbor in shared deformed configuration + normal_neighbor2me, & !< interface normal pointing from my neighbor to en in neighbor's lattice configuration + normal_neighbor2me_defConf, & !< interface normal pointing from my neighbor to en in shared deformed configuration + normal_me2neighbor, & !< interface normal pointing from en to my neighbor in my lattice configuration + normal_me2neighbor_defConf !< interface normal pointing from en to my neighbor in shared deformed configuration real(pReal) :: & area, & !< area of the current interface transmissivity, & !< overall transmissivity of dislocation flux to neighboring material point @@ -1224,16 +1224,16 @@ function rhoDotFlux(timestep,ph,me,ip,el) gdot = 0.0_pReal - rho = getRho(ph,me) + rho = getRho(ph,en) rhoSgl = rho(:,sgl) - rho0 = getRho0(ph,me) + rho0 = getRho0(ph,en) my_rhoSgl0 = rho0(:,sgl) - forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,ph),me) !ToDo: MD: I think we should use state0 here + forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,ph),en) !ToDo: MD: I think we should use state0 here gdot = rhoSgl(:,1:4) * v * spread(prm%b_sl,2,4) - forall (s = 1:ns, t = 1:4) v0(s,t) = plasticState(ph)%state0(iV(s,t,ph),me) + forall (s = 1:ns, t = 1:4) v0(s,t) = plasticState(ph)%state0(iV(s,t,ph),en) !**************************************************************************** !*** calculate dislocation fluxes (only for nonlocal plasticity) @@ -1268,8 +1268,8 @@ function rhoDotFlux(timestep,ph,me,ip,el) m(1:3,:,3) = -prm%slip_transverse m(1:3,:,4) = prm%slip_transverse - my_F = phase_mechanical_F(ph)%data(1:3,1:3,me) - my_Fe = matmul(my_F, math_inv33(phase_mechanical_Fp(ph)%data(1:3,1:3,me))) + my_F = phase_mechanical_F(ph)%data(1:3,1:3,en) + my_Fe = matmul(my_F, math_inv33(phase_mechanical_Fp(ph)%data(1:3,1:3,en))) neighbors: do n = 1,nIPneighbors @@ -1316,7 +1316,7 @@ function rhoDotFlux(timestep,ph,me,ip,el) .or. neighbor_rhoSgl0 < prm%rho_significant) & neighbor_rhoSgl0 = 0.0_pReal normal_neighbor2me_defConf = math_det33(Favg) * matmul(math_inv33(transpose(Favg)), & - IPareaNormal(1:3,neighbor_n,neighbor_ip,neighbor_el)) ! normal of the interface in (average) deformed configuration (pointing neighbor => me) + IPareaNormal(1:3,neighbor_n,neighbor_ip,neighbor_el)) ! normal of the interface in (average) deformed configuration (pointing neighbor => en) normal_neighbor2me = matmul(transpose(neighbor_Fe), normal_neighbor2me_defConf) & / math_det33(neighbor_Fe) ! interface normal in the lattice configuration of my neighbor area = IParea(neighbor_n,neighbor_ip,neighbor_el) * norm2(normal_neighbor2me) @@ -1325,7 +1325,7 @@ function rhoDotFlux(timestep,ph,me,ip,el) do t = 1,4 c = (t + 1) / 2 topp = t + mod(t,2) - mod(t+1,2) - if (neighbor_v0(s,t) * math_inner(m(1:3,s,t), normal_neighbor2me) > 0.0_pReal & ! flux from my neighbor to me == entering flux for me + if (neighbor_v0(s,t) * math_inner(m(1:3,s,t), normal_neighbor2me) > 0.0_pReal & ! flux from my neighbor to en == entering flux for en .and. v0(s,t) * neighbor_v0(s,t) >= 0.0_pReal ) then ! ... only if no sign change in flux density lineLength = neighbor_rhoSgl0(s,t) * neighbor_v0(s,t) & * math_inner(m(1:3,s,t), normal_neighbor2me) * area ! positive line length that wants to enter through this interface @@ -1344,7 +1344,7 @@ function rhoDotFlux(timestep,ph,me,ip,el) !* FLUX FROM ME TO MY NEIGHBOR !* This is not considered, if my opposite neighbor has a different constitutive law than nonlocal (still considered for nonlocal law with local properties). - !* Then, we assume, that the opposite(!) neighbor sends an equal amount of dislocations to me. + !* Then, we assume, that the opposite(!) neighbor sends an equal amount of dislocations to en. !* So the net flux in the direction of my neighbor is equal to zero: !* leaving flux to neighbor == entering flux from opposite neighbor !* In case of reduced transmissivity, part of the leaving flux is stored as dead dislocation density. @@ -1353,7 +1353,7 @@ function rhoDotFlux(timestep,ph,me,ip,el) if (phase_plasticity(material_phaseAt(1,opposite_el)) == PLASTICITY_NONLOCAL_ID) then normal_me2neighbor_defConf = math_det33(Favg) & - * matmul(math_inv33(transpose(Favg)),IPareaNormal(1:3,n,ip,el)) ! normal of the interface in (average) deformed configuration (pointing me => neighbor) + * matmul(math_inv33(transpose(Favg)),IPareaNormal(1:3,n,ip,el)) ! normal of the interface in (average) deformed configuration (pointing en => neighbor) normal_me2neighbor = matmul(transpose(my_Fe), normal_me2neighbor_defConf) & / math_det33(my_Fe) ! interface normal in my lattice configuration area = IParea(n,ip,el) * norm2(normal_me2neighbor) @@ -1361,7 +1361,7 @@ function rhoDotFlux(timestep,ph,me,ip,el) do s = 1,ns do t = 1,4 c = (t + 1) / 2 - if (v0(s,t) * math_inner(m(1:3,s,t), normal_me2neighbor) > 0.0_pReal ) then ! flux from me to my neighbor == leaving flux for me (might also be a pure flux from my mobile density to dead density if interface not at all transmissive) + if (v0(s,t) * math_inner(m(1:3,s,t), normal_me2neighbor) > 0.0_pReal ) then ! flux from en to my neighbor == leaving flux for en (might also be a pure flux from my mobile density to dead density if interface not at all transmissive) if (v0(s,t) * neighbor_v0(s,t) >= 0.0_pReal) then ! no sign change in flux density transmissivity = sum(compatibility(c,:,s,n,ip,el)**2.0_pReal) ! overall transmissivity from this slip system to my neighbor else ! sign change in flux density means sign change in stress which does not allow for dislocations to arive at the neighbor @@ -1403,13 +1403,13 @@ module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,i,e) integer :: & n, & ! neighbor index - me, & + en, & neighbor_e, & ! element index of my neighbor neighbor_i, & ! integration point index of my neighbor neighbor_me, & neighbor_phase, & ns, & ! number of active slip systems - s1, & ! slip system index (me) + s1, & ! slip system index (en) s2 ! slip system index (my neighbor) real(pReal), dimension(2,param(ph)%sum_N_sl,param(ph)%sum_N_sl,nIPneighbors) :: & my_compatibility ! my_compatibility for current element and ip @@ -1424,7 +1424,7 @@ module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,i,e) associate(prm => param(ph)) ns = prm%sum_N_sl - me = material_phaseMemberAt(1,i,e) + en = material_phaseMemberAt(1,i,e) !*** start out fully compatible my_compatibility = 0.0_pReal forall(s1 = 1:ns) my_compatibility(:,s1,s1,:) = 1.0_pReal @@ -1450,7 +1450,7 @@ module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,i,e) elseif (prm%chi_GB >= 0.0_pReal) then !* GRAIN BOUNDARY ! !* fixed transmissivity for adjacent ips with different texture (only if explicitly given in material.config) - if (any(dNeq(material_orientation0(1,ph,me)%asQuaternion(), & + if (any(dNeq(material_orientation0(1,ph,en)%asQuaternion(), & material_orientation0(1,neighbor_phase,neighbor_me)%asQuaternion())) .and. & (.not. phase_localPlasticity(neighbor_phase))) & forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = sqrt(prm%chi_GB) @@ -1767,21 +1767,21 @@ end subroutine kinetics !> @brief returns copy of current dislocation densities from state !> @details raw values is rectified !-------------------------------------------------------------------------------------------------- -pure function getRho(ph,me) +pure function getRho(ph,en) - integer, intent(in) :: ph, me + integer, intent(in) :: ph, en real(pReal), dimension(param(ph)%sum_N_sl,10) :: getRho associate(prm => param(ph)) - getRho = reshape(state(ph)%rho(:,me),[prm%sum_N_sl,10]) + getRho = reshape(state(ph)%rho(:,en),[prm%sum_N_sl,10]) ! ensure positive densities (not for imm, they have a sign) getRho(:,mob) = max(getRho(:,mob),0.0_pReal) getRho(:,dip) = max(getRho(:,dip),0.0_pReal) - where(abs(getRho) < max(prm%rho_min/geom(ph)%V_0(me)**(2.0_pReal/3.0_pReal),prm%rho_significant)) & + where(abs(getRho) < max(prm%rho_min/geom(ph)%V_0(en)**(2.0_pReal/3.0_pReal),prm%rho_significant)) & getRho = 0.0_pReal end associate @@ -1793,21 +1793,21 @@ end function getRho !> @brief returns copy of current dislocation densities from state !> @details raw values is rectified !-------------------------------------------------------------------------------------------------- -pure function getRho0(ph,me) +pure function getRho0(ph,en) - integer, intent(in) :: ph, me + integer, intent(in) :: ph, en real(pReal), dimension(param(ph)%sum_N_sl,10) :: getRho0 associate(prm => param(ph)) - getRho0 = reshape(state0(ph)%rho(:,me),[prm%sum_N_sl,10]) + getRho0 = reshape(state0(ph)%rho(:,en),[prm%sum_N_sl,10]) ! ensure positive densities (not for imm, they have a sign) getRho0(:,mob) = max(getRho0(:,mob),0.0_pReal) getRho0(:,dip) = max(getRho0(:,dip),0.0_pReal) - where (abs(getRho0) < max(prm%rho_min/geom(ph)%V_0(me)**(2.0_pReal/3.0_pReal),prm%rho_significant)) & + where (abs(getRho0) < max(prm%rho_min/geom(ph)%V_0(en)**(2.0_pReal/3.0_pReal),prm%rho_significant)) & getRho0 = 0.0_pReal end associate diff --git a/src/phase_mechanical_plastic_phenopowerlaw.f90 b/src/phase_mechanical_plastic_phenopowerlaw.f90 index 77c47907f..b2db9e346 100644 --- a/src/phase_mechanical_plastic_phenopowerlaw.f90 +++ b/src/phase_mechanical_plastic_phenopowerlaw.f90 @@ -283,7 +283,7 @@ end function plastic_phenopowerlaw_init !> @details asummes that deformation by dislocation glide affects twinned and untwinned volume ! equally (Taylor assumption). Twinning happens only in untwinned volume !-------------------------------------------------------------------------------------------------- -pure module subroutine phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) +pure module subroutine phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en) real(pReal), dimension(3,3), intent(out) :: & Lp !< plastic velocity gradient @@ -294,7 +294,7 @@ pure module subroutine phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) Mp !< Mandel stress integer, intent(in) :: & ph, & - me + en integer :: & i,k,l,m,n @@ -309,7 +309,7 @@ pure module subroutine phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) associate(prm => param(ph)) - call kinetics_slip(Mp,ph,me,gdot_slip_pos,gdot_slip_neg,dgdot_dtauslip_pos,dgdot_dtauslip_neg) + call kinetics_slip(Mp,ph,en,gdot_slip_pos,gdot_slip_neg,dgdot_dtauslip_pos,dgdot_dtauslip_neg) slipSystems: do i = 1, prm%sum_N_sl Lp = Lp + (gdot_slip_pos(i)+gdot_slip_neg(i))*prm%P_sl(1:3,1:3,i) forall (k=1:3,l=1:3,m=1:3,n=1:3) & @@ -318,7 +318,7 @@ pure module subroutine phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) + dgdot_dtauslip_neg(i) * prm%P_sl(k,l,i) * prm%nonSchmid_neg(m,n,i) enddo slipSystems - call kinetics_twin(Mp,ph,me,gdot_twin,dgdot_dtautwin) + call kinetics_twin(Mp,ph,en,gdot_twin,dgdot_dtautwin) twinSystems: do i = 1, prm%sum_N_tw Lp = Lp + gdot_twin(i)*prm%P_tw(1:3,1:3,i) forall (k=1:3,l=1:3,m=1:3,n=1:3) & @@ -334,13 +334,13 @@ end subroutine phenopowerlaw_LpAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief Calculate the rate of change of microstructure. !-------------------------------------------------------------------------------------------------- -module subroutine phenopowerlaw_dotState(Mp,ph,me) +module subroutine phenopowerlaw_dotState(Mp,ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress integer, intent(in) :: & ph, & - me + en real(pReal) :: & c_SlipSlip,c_TwinSlip,c_TwinTwin, & @@ -353,8 +353,8 @@ module subroutine phenopowerlaw_dotState(Mp,ph,me) associate(prm => param(ph), stt => state(ph), & dot => dotState(ph)) - sumGamma = sum(stt%gamma_slip(:,me)) - sumF = sum(stt%gamma_twin(:,me)/prm%gamma_char) + sumGamma = sum(stt%gamma_slip(:,en)) + sumF = sum(stt%gamma_twin(:,en)/prm%gamma_char) !-------------------------------------------------------------------------------------------------- ! system-independent (nonlinear) prefactors to M_Xx (X influenced by x) matrices @@ -366,23 +366,23 @@ module subroutine phenopowerlaw_dotState(Mp,ph,me) ! calculate left and right vectors left_SlipSlip = 1.0_pReal + prm%h_int xi_slip_sat_offset = prm%f_sat_sl_tw*sqrt(sumF) - right_SlipSlip = abs(1.0_pReal-stt%xi_slip(:,me) / (prm%xi_inf_sl+xi_slip_sat_offset)) **prm%a_sl & - * sign(1.0_pReal,1.0_pReal-stt%xi_slip(:,me) / (prm%xi_inf_sl+xi_slip_sat_offset)) + right_SlipSlip = abs(1.0_pReal-stt%xi_slip(:,en) / (prm%xi_inf_sl+xi_slip_sat_offset)) **prm%a_sl & + * sign(1.0_pReal,1.0_pReal-stt%xi_slip(:,en) / (prm%xi_inf_sl+xi_slip_sat_offset)) !-------------------------------------------------------------------------------------------------- ! shear rates - call kinetics_slip(Mp,ph,me,gdot_slip_pos,gdot_slip_neg) - dot%gamma_slip(:,me) = abs(gdot_slip_pos+gdot_slip_neg) - call kinetics_twin(Mp,ph,me,dot%gamma_twin(:,me)) + call kinetics_slip(Mp,ph,en,gdot_slip_pos,gdot_slip_neg) + dot%gamma_slip(:,en) = abs(gdot_slip_pos+gdot_slip_neg) + call kinetics_twin(Mp,ph,en,dot%gamma_twin(:,en)) !-------------------------------------------------------------------------------------------------- ! hardening - dot%xi_slip(:,me) = c_SlipSlip * left_SlipSlip * & - matmul(prm%h_sl_sl,dot%gamma_slip(:,me)*right_SlipSlip) & - + matmul(prm%h_sl_tw,dot%gamma_twin(:,me)) + dot%xi_slip(:,en) = c_SlipSlip * left_SlipSlip * & + matmul(prm%h_sl_sl,dot%gamma_slip(:,en)*right_SlipSlip) & + + matmul(prm%h_sl_tw,dot%gamma_twin(:,en)) - dot%xi_twin(:,me) = c_TwinSlip * matmul(prm%h_tw_sl,dot%gamma_slip(:,me)) & - + c_TwinTwin * matmul(prm%h_tw_tw,dot%gamma_twin(:,me)) + dot%xi_twin(:,en) = c_TwinSlip * matmul(prm%h_tw_sl,dot%gamma_slip(:,en)) & + + c_TwinTwin * matmul(prm%h_tw_tw,dot%gamma_twin(:,en)) end associate end subroutine phenopowerlaw_dotState @@ -430,14 +430,14 @@ end subroutine plastic_phenopowerlaw_results ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end. !-------------------------------------------------------------------------------------------------- -pure subroutine kinetics_slip(Mp,ph,me, & +pure subroutine kinetics_slip(Mp,ph,en, & gdot_slip_pos,gdot_slip_neg,dgdot_dtau_slip_pos,dgdot_dtau_slip_neg) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress integer, intent(in) :: & ph, & - me + en real(pReal), intent(out), dimension(param(ph)%sum_N_sl) :: & gdot_slip_pos, & @@ -461,14 +461,14 @@ pure subroutine kinetics_slip(Mp,ph,me, & where(dNeq0(tau_slip_pos)) gdot_slip_pos = prm%dot_gamma_0_sl * merge(0.5_pReal,1.0_pReal, prm%nonSchmidActive) & ! 1/2 if non-Schmid active - * sign(abs(tau_slip_pos/stt%xi_slip(:,me))**prm%n_sl, tau_slip_pos) + * sign(abs(tau_slip_pos/stt%xi_slip(:,en))**prm%n_sl, tau_slip_pos) else where gdot_slip_pos = 0.0_pReal end where where(dNeq0(tau_slip_neg)) gdot_slip_neg = prm%dot_gamma_0_sl * 0.5_pReal & ! only used if non-Schmid active, always 1/2 - * sign(abs(tau_slip_neg/stt%xi_slip(:,me))**prm%n_sl, tau_slip_neg) + * sign(abs(tau_slip_neg/stt%xi_slip(:,en))**prm%n_sl, tau_slip_neg) else where gdot_slip_neg = 0.0_pReal end where @@ -499,14 +499,14 @@ end subroutine kinetics_slip ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end. !-------------------------------------------------------------------------------------------------- -pure subroutine kinetics_twin(Mp,ph,me,& +pure subroutine kinetics_twin(Mp,ph,en,& gdot_twin,dgdot_dtau_twin) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress integer, intent(in) :: & ph, & - me + en real(pReal), dimension(param(ph)%sum_N_tw), intent(out) :: & gdot_twin @@ -524,8 +524,8 @@ pure subroutine kinetics_twin(Mp,ph,me,& enddo where(tau_twin > 0.0_pReal) - gdot_twin = (1.0_pReal-sum(stt%gamma_twin(:,me)/prm%gamma_char)) & ! only twin in untwinned volume fraction - * prm%dot_gamma_0_tw*(abs(tau_twin)/stt%xi_twin(:,me))**prm%n_tw + gdot_twin = (1.0_pReal-sum(stt%gamma_twin(:,en)/prm%gamma_char)) & ! only twin in untwinned volume fraction + * prm%dot_gamma_0_tw*(abs(tau_twin)/stt%xi_twin(:,en))**prm%n_tw else where gdot_twin = 0.0_pReal end where diff --git a/src/phase_thermal.f90 b/src/phase_thermal.f90 index b51ac74f5..8d6ccaf6f 100644 --- a/src/phase_thermal.f90 +++ b/src/phase_thermal.f90 @@ -26,7 +26,7 @@ submodule(phase) thermal integer(kind(THERMAL_UNDEFINED_ID)), dimension(:,:), allocatable :: & thermal_source - type(tDataContainer), dimension(:), allocatable :: current ! ?? not very telling name. Better: "field" ?? MD: current(ho)%T(me) reads quite good + type(tDataContainer), dimension(:), allocatable :: current ! ?? not very telling name. Better: "field" ?? MD: current(ho)%T(en) reads quite good type(tThermalParameters), dimension(:), allocatable :: param @@ -46,23 +46,23 @@ submodule(phase) thermal end function externalheat_init - module subroutine externalheat_dotState(ph, me) + module subroutine externalheat_dotState(ph, en) integer, intent(in) :: & ph, & - me + en end subroutine externalheat_dotState - module function dissipation_f_T(ph,me) result(f_T) + module function dissipation_f_T(ph,en) result(f_T) integer, intent(in) :: & ph, & - me + en real(pReal) :: f_T end function dissipation_f_T - module function externalheat_f_T(ph,me) result(f_T) + module function externalheat_f_T(ph,en) result(f_T) integer, intent(in) :: & ph, & - me + en real(pReal) :: f_T end function externalheat_f_T @@ -137,9 +137,9 @@ end subroutine thermal_init !---------------------------------------------------------------------------------------------- !< @brief calculates thermal dissipation rate !---------------------------------------------------------------------------------------------- -module function phase_f_T(ph,me) result(f) +module function phase_f_T(ph,en) result(f) - integer, intent(in) :: ph, me + integer, intent(in) :: ph, en real(pReal) :: f @@ -152,10 +152,10 @@ module function phase_f_T(ph,me) result(f) select case(thermal_source(so,ph)) case (THERMAL_DISSIPATION_ID) - f = f + dissipation_f_T(ph,me) + f = f + dissipation_f_T(ph,en) case (THERMAL_EXTERNALHEAT_ID) - f = f + externalheat_f_T(ph,me) + f = f + externalheat_f_T(ph,en) end select @@ -167,9 +167,9 @@ end function phase_f_T !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -function phase_thermal_collectDotState(ph,me) result(broken) +function phase_thermal_collectDotState(ph,en) result(broken) - integer, intent(in) :: ph, me + integer, intent(in) :: ph, en logical :: broken integer :: i @@ -180,9 +180,9 @@ function phase_thermal_collectDotState(ph,me) result(broken) SourceLoop: do i = 1, thermal_Nsources(ph) if (thermal_source(i,ph) == THERMAL_EXTERNALHEAT_ID) & - call externalheat_dotState(ph,me) + call externalheat_dotState(ph,en) - broken = broken .or. any(IEEE_is_NaN(thermalState(ph)%p(i)%dotState(:,me))) + broken = broken .or. any(IEEE_is_NaN(thermalState(ph)%p(i)%dotState(:,en))) enddo SourceLoop @@ -218,14 +218,14 @@ module function phase_K_T(co,ce) result(K) end function phase_K_T -module function thermal_stress(Delta_t,ph,me) result(converged_) ! ?? why is this called "stress" when it seems closer to "updateState" ?? +module function thermal_stress(Delta_t,ph,en) result(converged_) ! ?? why is this called "stress" when it seems closer to "updateState" ?? real(pReal), intent(in) :: Delta_t - integer, intent(in) :: ph, me + integer, intent(in) :: ph, en logical :: converged_ - converged_ = .not. integrateThermalState(Delta_t,ph,me) + converged_ = .not. integrateThermalState(Delta_t,ph,en) end function thermal_stress @@ -233,10 +233,10 @@ end function thermal_stress !-------------------------------------------------------------------------------------------------- !> @brief integrate state with 1st order explicit Euler method !-------------------------------------------------------------------------------------------------- -function integrateThermalState(Delta_t, ph,me) result(broken) +function integrateThermalState(Delta_t, ph,en) result(broken) real(pReal), intent(in) :: Delta_t - integer, intent(in) :: ph, me + integer, intent(in) :: ph, en logical :: & broken @@ -244,13 +244,13 @@ function integrateThermalState(Delta_t, ph,me) result(broken) so, & sizeDotState - broken = phase_thermal_collectDotState(ph,me) + broken = phase_thermal_collectDotState(ph,en) if (broken) return do so = 1, thermal_Nsources(ph) sizeDotState = thermalState(ph)%p(so)%sizeDotState - thermalState(ph)%p(so)%state(1:sizeDotState,me) = thermalState(ph)%p(so)%state0(1:sizeDotState,me) & - + thermalState(ph)%p(so)%dotState(1:sizeDotState,me) * Delta_t + thermalState(ph)%p(so)%state(1:sizeDotState,en) = thermalState(ph)%p(so)%state0(1:sizeDotState,en) & + + thermalState(ph)%p(so)%dotState(1:sizeDotState,en) * Delta_t enddo end function integrateThermalState @@ -273,13 +273,13 @@ end subroutine thermal_forward !---------------------------------------------------------------------------------------------- !< @brief Get temperature (for use by non-thermal physics) !---------------------------------------------------------------------------------------------- -module function thermal_T(ph,me) result(T) +module function thermal_T(ph,en) result(T) - integer, intent(in) :: ph, me + integer, intent(in) :: ph, en real(pReal) :: T - T = current(ph)%T(me) + T = current(ph)%T(en) end function thermal_T @@ -287,13 +287,13 @@ end function thermal_T !---------------------------------------------------------------------------------------------- !< @brief Get rate of temperature (for use by non-thermal physics) !---------------------------------------------------------------------------------------------- -module function thermal_dot_T(ph,me) result(dot_T) +module function thermal_dot_T(ph,en) result(dot_T) - integer, intent(in) :: ph, me + integer, intent(in) :: ph, en real(pReal) :: dot_T - dot_T = current(ph)%dot_T(me) + dot_T = current(ph)%dot_T(en) end function thermal_dot_T diff --git a/src/phase_thermal_dissipation.f90 b/src/phase_thermal_dissipation.f90 index 3a4ee651a..cbdf5bb99 100644 --- a/src/phase_thermal_dissipation.f90 +++ b/src/phase_thermal_dissipation.f90 @@ -69,15 +69,15 @@ end function dissipation_init !-------------------------------------------------------------------------------------------------- !> @brief Ninstancess dissipation rate !-------------------------------------------------------------------------------------------------- -module function dissipation_f_T(ph,me) result(f_T) +module function dissipation_f_T(ph,en) result(f_T) - integer, intent(in) :: ph, me + integer, intent(in) :: ph, en real(pReal) :: & f_T associate(prm => param(ph)) - f_T = prm%kappa*sum(abs(mechanical_S(ph,me)*mechanical_L_p(ph,me))) + f_T = prm%kappa*sum(abs(mechanical_S(ph,en)*mechanical_L_p(ph,en))) end associate end function dissipation_f_T diff --git a/src/phase_thermal_externalheat.f90 b/src/phase_thermal_externalheat.f90 index 6d4403ab8..46da127f3 100644 --- a/src/phase_thermal_externalheat.f90 +++ b/src/phase_thermal_externalheat.f90 @@ -81,18 +81,18 @@ end function externalheat_init !> @brief rate of change of state !> @details state only contains current time to linearly interpolate given heat powers !-------------------------------------------------------------------------------------------------- -module subroutine externalheat_dotState(ph, me) +module subroutine externalheat_dotState(ph, en) integer, intent(in) :: & ph, & - me + en integer :: & so so = source_thermal_externalheat_offset(ph) - thermalState(ph)%p(so)%dotState(1,me) = 1.0_pReal ! state is current time + thermalState(ph)%p(so)%dotState(1,en) = 1.0_pReal ! state is current time end subroutine externalheat_dotState @@ -100,11 +100,11 @@ end subroutine externalheat_dotState !-------------------------------------------------------------------------------------------------- !> @brief returns local heat generation rate !-------------------------------------------------------------------------------------------------- -module function externalheat_f_T(ph,me) result(f_T) +module function externalheat_f_T(ph,en) result(f_T) integer, intent(in) :: & ph, & - me + en real(pReal) :: & f_T @@ -117,14 +117,14 @@ module function externalheat_f_T(ph,me) result(f_T) associate(prm => param(ph)) do interval = 1, prm%nIntervals ! scan through all rate segments - frac_time = (thermalState(ph)%p(so)%state(1,me) - prm%t_n(interval)) & + frac_time = (thermalState(ph)%p(so)%state(1,en) - prm%t_n(interval)) & / (prm%t_n(interval+1) - prm%t_n(interval)) ! fractional time within segment if ( (frac_time < 0.0_pReal .and. interval == 1) & .or. (frac_time >= 1.0_pReal .and. interval == prm%nIntervals) & .or. (frac_time >= 0.0_pReal .and. frac_time < 1.0_pReal) ) & f_T = prm%f_T(interval ) * (1.0_pReal - frac_time) + & prm%f_T(interval+1) * frac_time ! interpolate heat rate between segment boundaries... - ! ...or extrapolate if outside me bounds + ! ...or extrapolate if outside of bounds enddo end associate From 845f724ac8a580cdc29c71a719eed665eb905032 Mon Sep 17 00:00:00 2001 From: Test User Date: Sun, 25 Apr 2021 18:59:10 +0200 Subject: [PATCH 207/219] [skip ci] updated version information after successful test of v3.0.0-alpha3-11-gb7777bc74 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 543799db9..a7579b70a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha3-2-gd0dd1fd83 +v3.0.0-alpha3-11-gb7777bc74 From 68a839ed979787161b84430513e1c8881f19e947 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 25 Apr 2021 17:34:41 +0200 Subject: [PATCH 208/219] typo + improved help --- python/damask/_result.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 6daeffbc2..d73c678d8 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -400,8 +400,7 @@ class Result: Rename/move datasets (within the same group/folder). This operation is discouraged because the history of the - data becomes untracable and scientific integrity cannot be - ensured. + data becomes untraceable and data integrity is not ensured. Parameters ---------- @@ -442,8 +441,7 @@ class Result: Remove/delete datasets. This operation is discouraged because the history of the - data becomes untracable and scientific integrity cannot be - ensured. + data becomes untraceable and data integrity is not ensured. Parameters ---------- @@ -596,7 +594,7 @@ class Result: >>> r = damask.Result('my_file.hdf5') >>> r.add_calculation('np.sum(#rho_mob#,axis=1)','rho_mob_total', ... '1/m²','total mobile dislocation density') - >>> r.add_calculation(''np.sum(#rho_dip#,axis=1)',rho_dip_total', + >>> r.add_calculation('np.sum(#rho_dip#,axis=1)','rho_dip_total', ... '1/m²','total dislocation dipole density') >>> r.add_calculation('#rho_dip_total#+#rho_mob_total','rho_total', ... '1/m²','total dislocation density') @@ -953,6 +951,13 @@ class Result: F : str, optional Name of deformation gradient dataset. Defaults to 'F'. + Notes + ----- + The definition of the second Piola-Kirchhoff (S) stress follows + the standard nonlinear continuum mechanics definition. It does + NOT take the different configurations into account as it would + be required for the crystal plasticity definition of S. + """ self._add_generic_pointwise(self._add_stress_second_Piola_Kirchhoff,{'P':P,'F':F}) From 62c987badfc6500ecd808e77d95079085f39de51 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 25 Apr 2021 22:52:13 +0200 Subject: [PATCH 209/219] add tracer to vtk files --- python/damask/_result.py | 7 ++++++- .../Result/12grains6x7x8_tensionY.hdf5 | Bin 2295784 -> 2299880 bytes .../Result/save_VTK/test_vtk[0-0-0].md5 | 2 +- .../Result/save_VTK/test_vtk[0-0-1].md5 | 2 +- .../Result/save_VTK/test_vtk[0-0-2].md5 | 2 +- .../Result/save_VTK/test_vtk[1-0-0].md5 | 2 +- .../Result/save_VTK/test_vtk[1-0-1].md5 | 2 +- .../Result/save_VTK/test_vtk[1-0-2].md5 | 2 +- python/tests/test_Result.py | 2 +- src/results.f90 | 8 +++++--- 10 files changed, 18 insertions(+), 11 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index d73c678d8..e2103d802 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -98,7 +98,7 @@ class Result: self.version_major = f.attrs['DADF5_version_major'] self.version_minor = f.attrs['DADF5_version_minor'] - if self.version_major != 0 or not 12 <= self.version_minor <= 12: + if self.version_major != 0 or not 12 <= self.version_minor <= 13: raise TypeError(f'Unsupported DADF5 version {self.version_major}.{self.version_minor}') self.structured = 'cells' in f['geometry'].attrs.keys() @@ -1407,6 +1407,7 @@ class Result: v = self.geometry0 elif mode.lower()=='point': v = VTK.from_poly_data(self.coordinates0_point) + v.set_comments(util.execution_stamp('Result','save_VTK')) N_digits = int(np.floor(np.log10(max(1,int(self.increments[-1][10:])))))+1 @@ -1419,6 +1420,10 @@ class Result: at_cell_ph,in_data_ph,at_cell_ho,in_data_ho = self._mappings() with h5py.File(self.fname,'r') as f: + if self.version_minor >= 13: + creator = f.attrs['creator'] if h5py3 else f.attrs['creator'].decode() + created = f.attrs['created'] if h5py3 else f.attrs['created'].decode() + v.add_comments(f'{creator} ({created})') for inc in util.show_progress(self.visible['increments']): diff --git a/python/tests/reference/Result/12grains6x7x8_tensionY.hdf5 b/python/tests/reference/Result/12grains6x7x8_tensionY.hdf5 index 9fa9006ad09e7408bfc249aecc50bbf27c2af1f8..1d914f8bb6fac4bd86d9421dbec5f564bd3185e5 100644 GIT binary patch delta 31127 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 XzjNo(o&q(FCs?MiddWb3qwoI$wQ}WG delta 30729 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 diff --git a/python/tests/reference/Result/save_VTK/test_vtk[0-0-0].md5 b/python/tests/reference/Result/save_VTK/test_vtk[0-0-0].md5 index 838037bb2..2d6393540 100644 --- a/python/tests/reference/Result/save_VTK/test_vtk[0-0-0].md5 +++ b/python/tests/reference/Result/save_VTK/test_vtk[0-0-0].md5 @@ -1 +1 @@ -3b83384def67552ab7dd211efc0d54fd \ No newline at end of file +0f68c932b85aac1d30e03e05a16c4605 \ No newline at end of file diff --git a/python/tests/reference/Result/save_VTK/test_vtk[0-0-1].md5 b/python/tests/reference/Result/save_VTK/test_vtk[0-0-1].md5 index 7ceffc337..9ef213fd3 100644 --- a/python/tests/reference/Result/save_VTK/test_vtk[0-0-1].md5 +++ b/python/tests/reference/Result/save_VTK/test_vtk[0-0-1].md5 @@ -1 +1 @@ -c32c86ed50dbb39a93ca2a2ebe47d9cb \ No newline at end of file +b206ef9e7a096586c7d71d58fc7278bd \ No newline at end of file diff --git a/python/tests/reference/Result/save_VTK/test_vtk[0-0-2].md5 b/python/tests/reference/Result/save_VTK/test_vtk[0-0-2].md5 index f5b7daec3..d1f08336d 100644 --- a/python/tests/reference/Result/save_VTK/test_vtk[0-0-2].md5 +++ b/python/tests/reference/Result/save_VTK/test_vtk[0-0-2].md5 @@ -1 +1 @@ -ead4f6fcaff174fddc041d701e54ac60 \ No newline at end of file +11bd422f0a6c78ee1d3c939b1fccf1ee \ No newline at end of file diff --git a/python/tests/reference/Result/save_VTK/test_vtk[1-0-0].md5 b/python/tests/reference/Result/save_VTK/test_vtk[1-0-0].md5 index df00a513f..2f7077569 100644 --- a/python/tests/reference/Result/save_VTK/test_vtk[1-0-0].md5 +++ b/python/tests/reference/Result/save_VTK/test_vtk[1-0-0].md5 @@ -1 +1 @@ -bde8b728110c2c05a6a4740f7c5f9c06 \ No newline at end of file +541f423cfde8e2a98582491f7af3add5 \ No newline at end of file diff --git a/python/tests/reference/Result/save_VTK/test_vtk[1-0-1].md5 b/python/tests/reference/Result/save_VTK/test_vtk[1-0-1].md5 index 35c577900..e1c35f93d 100644 --- a/python/tests/reference/Result/save_VTK/test_vtk[1-0-1].md5 +++ b/python/tests/reference/Result/save_VTK/test_vtk[1-0-1].md5 @@ -1 +1 @@ -e09bfa9248283fc390003ad28d15d36e \ No newline at end of file +82e309984cab644fd94f433d5ec24133 \ No newline at end of file diff --git a/python/tests/reference/Result/save_VTK/test_vtk[1-0-2].md5 b/python/tests/reference/Result/save_VTK/test_vtk[1-0-2].md5 index d5874d88b..c9125e234 100644 --- a/python/tests/reference/Result/save_VTK/test_vtk[1-0-2].md5 +++ b/python/tests/reference/Result/save_VTK/test_vtk[1-0-2].md5 @@ -1 +1 @@ -3f21254164f96de8ee4a28249ae72cc6 \ No newline at end of file +f1f85bcdba23e3e4001512c1c6c4707a \ No newline at end of file diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 56bc4a00f..9d9a5fc74 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -333,7 +333,7 @@ class TestResult: @pytest.mark.parametrize('output',['F','*',['P']],ids=range(3)) @pytest.mark.parametrize('fname',['12grains6x7x8_tensionY.hdf5'],ids=range(1)) @pytest.mark.parametrize('inc',[4,0],ids=range(2)) - def test_vtk(self,request,tmp_path,ref_path,update,output,fname,inc): + def test_vtk(self,request,tmp_path,ref_path,update,patch_execution_stamp,patch_datetime_now,output,fname,inc): result = Result(ref_path/fname).view('increments',inc) os.chdir(tmp_path) result.save_VTK(output) diff --git a/src/results.f90 b/src/results.f90 index 90727b9c3..f0af4a1cb 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -57,7 +57,7 @@ subroutine results_init(restart) logical, intent(in) :: restart - character(len=pStringLen) :: commandLine + character(len=pPathLen) :: commandLine print'(/,a)', ' <<<+- results init -+>>>'; flush(IO_STDOUT) @@ -67,8 +67,10 @@ subroutine results_init(restart) if(.not. restart) then resultsFile = HDF5_openFile(getSolverJobName()//'.hdf5','w') call results_addAttribute('DADF5_version_major',0) - call results_addAttribute('DADF5_version_minor',12) - call results_addAttribute('DAMASK_version',DAMASKVERSION) + call results_addAttribute('DADF5_version_minor',13) + call get_command_argument(0,commandLine) + call results_addAttribute('creator',trim(commandLine)//' '//DAMASKVERSION) + call results_addAttribute('created',now()) call get_command(commandLine) call results_addAttribute('call',trim(commandLine)) call results_closeGroup(results_addGroup('cell_to')) From de79d2d897647c0d7ff24bf32d44b2cbbf90a312 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 26 Apr 2021 00:22:37 +0200 Subject: [PATCH 210/219] test handling of Marc results --- python/damask/_result.py | 2 +- .../reference/Result/check_compile_job1.hdf5 | Bin 0 -> 61584 bytes python/tests/test_Result.py | 13 +++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 python/tests/reference/Result/check_compile_job1.hdf5 diff --git a/python/damask/_result.py b/python/damask/_result.py index e2103d802..cf30bf624 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -505,7 +505,7 @@ class Result: return grid_filters.coordinates0_point(self.cells,self.size,self.origin).reshape(-1,3,order='F') else: with h5py.File(self.fname,'r') as f: - return f['geometry/x_c'][()] + return f['geometry/x_p'][()] @property def coordinates0_node(self): diff --git a/python/tests/reference/Result/check_compile_job1.hdf5 b/python/tests/reference/Result/check_compile_job1.hdf5 new file mode 100644 index 0000000000000000000000000000000000000000..2634c26ce293a652b55d92694125c662081dfca1 GIT binary patch literal 61584 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 len(c_p) + @pytest.mark.parametrize('mode',['point','cell']) def test_vtk_mode(self,tmp_path,single_phase,mode): os.chdir(tmp_path) From 478665b7cd5cb5d45a9a7780b2ef8e03c406f3fe Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Mon, 26 Apr 2021 10:26:50 +0200 Subject: [PATCH 211/219] polishing --- src/phase_mechanical_plastic_dislotungsten.f90 | 2 +- src/phase_mechanical_plastic_kinehardening.f90 | 2 +- src/phase_mechanical_plastic_nonlocal.f90 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/phase_mechanical_plastic_dislotungsten.f90 b/src/phase_mechanical_plastic_dislotungsten.f90 index aaa3885b9..bb53684e1 100644 --- a/src/phase_mechanical_plastic_dislotungsten.f90 +++ b/src/phase_mechanical_plastic_dislotungsten.f90 @@ -17,7 +17,7 @@ submodule(phase:plastic) dislotungsten D_0 = 1.0_pReal, & !< prefactor for self-diffusion coefficient Q_cl = 1.0_pReal !< activation energy for dislocation climb real(pReal), allocatable, dimension(:) :: & - b_sl, & !< magnitude en Burgers vector [m] + b_sl, & !< magnitude of Burgers vector [m] D_a, & i_sl, & !< Adj. parameter for distance between 2 forest dislocations f_at, & !< factor to calculate atomic volume diff --git a/src/phase_mechanical_plastic_kinehardening.f90 b/src/phase_mechanical_plastic_kinehardening.f90 index 7acfd2675..18f467617 100644 --- a/src/phase_mechanical_plastic_kinehardening.f90 +++ b/src/phase_mechanical_plastic_kinehardening.f90 @@ -336,7 +336,7 @@ module subroutine plastic_kinehardening_deltaState(Mp,ph,en) !-------------------------------------------------------------------------------------------------- -! switch in sense en shear? +! switch in sense of shear? where(dNeq(sense,stt%sense(:,en),0.1_pReal)) dlt%sense (:,en) = sense - stt%sense(:,en) ! switch sense dlt%chi0 (:,en) = abs(stt%crss_back(:,en)) - stt%chi0(:,en) ! remember current backstress magnitude diff --git a/src/phase_mechanical_plastic_nonlocal.f90 b/src/phase_mechanical_plastic_nonlocal.f90 index cf34597b6..05ba371ce 100644 --- a/src/phase_mechanical_plastic_nonlocal.f90 +++ b/src/phase_mechanical_plastic_nonlocal.f90 @@ -1118,7 +1118,7 @@ module subroutine nonlocal_dotState(Mp, Temperature,timestep, & * 0.25_pReal * sqrt(stt%rho_forest(s,en)) * (dUpper(s,2) + dLower(s,2)) * prm%f_ed - !*** thermally activated annihilation en edge dipoles by climb + !*** thermally activated annihilation of edge dipoles by climb rhoDotThermalAnnihilation = 0.0_pReal selfDiffusion = prm%D_0 * exp(-prm%Q_cl / (kB * Temperature)) vClimb = prm%V_at * selfDiffusion * prm%mu & From b1bbe5528bb530f16ec863c6f9348d36e1f6de2c Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Mon, 26 Apr 2021 17:09:11 +0000 Subject: [PATCH 212/219] [skip ci] fixed mistake (R --> Q) in example --- python/damask/_rotation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 3bd84fcb1..c329464ed 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -36,7 +36,7 @@ class Rotation: >>> import numpy as np >>> Q = damask.Rotation.from_random() >>> a = np.random.rand(3) - >>> b = R @ a + >>> b = Q @ a >>> np.allclose(np.dot(Q.as_matrix(),a),b) True From e8b01e375defa095c0ab6774556dbab9206c97c6 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 26 Apr 2021 20:19:37 +0200 Subject: [PATCH 213/219] [skip ci] updated version information after successful test of v3.0.0-alpha3-16-g340542cd4 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index a7579b70a..d3d10f1fe 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha3-11-gb7777bc74 +v3.0.0-alpha3-16-g340542cd4 From 5567512f737ffcc2e915a66102e2cbcdadbc05a8 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Mon, 26 Apr 2021 14:26:16 -0400 Subject: [PATCH 214/219] removed unnecessary f-strings; added any -x to increments view --- python/damask/_result.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index cf30bf624..c424207e5 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -112,11 +112,11 @@ class Result: self.increments = sorted([i for i in f.keys() if r.match(i)],key=util.natural_sort) self.times = [round(f[i].attrs['t/s'],12) for i in self.increments] - self.N_materialpoints, self.N_constituents = np.shape(f[f'cell_to/phase']) + self.N_materialpoints, self.N_constituents = np.shape(f['cell_to/phase']) - self.homogenization = f[f'cell_to/homogenization']['label'].astype('str') + self.homogenization = f['cell_to/homogenization']['label'].astype('str') self.homogenizations = sorted(np.unique(self.homogenization),key=util.natural_sort) - self.phase = f[f'cell_to/phase']['label'].astype('str') + self.phase = f['cell_to/phase']['label'].astype('str') self.phases = sorted(np.unique(self.phase),key=util.natural_sort) self.fields = [] @@ -189,8 +189,7 @@ class Result: if what == 'increments': choice = [c if isinstance(c,str) and c.startswith('increment_') else - f'increment_{c}' for c in choice] - if datasets == -1: choice = [self.increments[-1]] + self.increments[c] if c<0 else f'increment_{c}' for c in choice] elif what == 'times': what = 'increments' if choice == ['*']: @@ -953,10 +952,10 @@ class Result: Notes ----- - The definition of the second Piola-Kirchhoff (S) stress follows - the standard nonlinear continuum mechanics definition. It does - NOT take the different configurations into account as it would - be required for the crystal plasticity definition of S. + The definition of the second Piola-Kirchhoff stress (S = [F^-1 P]_sym) + follows the standard definition in nonlinear continuum mechanics. + As such, no intermediate configuration, for instance that reached by F_p, + is taken into account. """ self._add_generic_pointwise(self._add_stress_second_Piola_Kirchhoff,{'P':P,'F':F}) From c0958a934ee5f8b6c7585f45dbd166d9771d2663 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 26 Apr 2021 22:08:11 +0200 Subject: [PATCH 215/219] [skip ci] updated version information after successful test of v3.0.0-alpha3-21-g55333f7e3 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index a7579b70a..2c06d405b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha3-11-gb7777bc74 +v3.0.0-alpha3-21-g55333f7e3 From ba938f17463aa3c3e597ad354c8a9736f85f0664 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Mon, 26 Apr 2021 17:56:15 -0400 Subject: [PATCH 216/219] need to check for isinstance(int) --- python/damask/_result.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index c424207e5..0520f08f2 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -189,7 +189,8 @@ class Result: if what == 'increments': choice = [c if isinstance(c,str) and c.startswith('increment_') else - self.increments[c] if c<0 else f'increment_{c}' for c in choice] + self.increments[c] if isinstance(c,int) and c<0 else + f'increment_{c}' for c in choice] elif what == 'times': what = 'increments' if choice == ['*']: From 1b98597bb17f1be6c7d995cbbfed80abe3a55bdf Mon Sep 17 00:00:00 2001 From: Test User Date: Tue, 27 Apr 2021 04:18:28 +0200 Subject: [PATCH 217/219] [skip ci] updated version information after successful test of v3.0.0-alpha3-37-ge9cfb2f96 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index d3d10f1fe..c2cb2e07b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha3-16-g340542cd4 +v3.0.0-alpha3-37-ge9cfb2f96 From ff8ce3840b39eccd9718d4a85240897968ffac72 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 28 Apr 2021 07:57:20 +0200 Subject: [PATCH 218/219] handle infinite loop --- PRIVATE | 2 +- python/damask/seeds.py | 19 +++++++++++++------ python/setup.py | 2 +- python/tests/test_seeds.py | 9 +++++++++ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/PRIVATE b/PRIVATE index 7f0594060..ab64793bb 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 7f0594060779d9a8a4e774d558134309ab77b96e +Subproject commit ab64793bb04c506d815ebc850672ed0f2d013e67 diff --git a/python/damask/seeds.py b/python/damask/seeds.py index aeab2e64a..02a050e66 100644 --- a/python/damask/seeds.py +++ b/python/damask/seeds.py @@ -71,18 +71,25 @@ def from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=True,rng_seed= coords = _np.empty((N_seeds,3)) coords[0] = rng.random(3) * size - i = 1 + s = 1 + i = 0 progress = util._ProgressBar(N_seeds+1,'',50) - while i < N_seeds: + while s < N_seeds: candidates = rng.random((N_candidates,3))*_np.broadcast_to(size,(N_candidates,3)) - tree = _spatial.cKDTree(coords[:i],boxsize=size) if periodic else \ - _spatial.cKDTree(coords[:i]) + tree = _spatial.cKDTree(coords[:s],boxsize=size) if periodic else \ + _spatial.cKDTree(coords[:s]) distances, dev_null = tree.query(candidates) best = distances.argmax() if distances[best] > distance: # require minimum separation - coords[i] = candidates[best] # maximum separation to existing point cloud + coords[s] = candidates[best] # maximum separation to existing point cloud + s += 1 + progress.update(s) + i = 0 + else: i += 1 - progress.update(i) + + if i == 100: + raise ValueError('Seeding not possible') return coords diff --git a/python/setup.py b/python/setup.py index f6ba83b7b..e590a1197 100644 --- a/python/setup.py +++ b/python/setup.py @@ -4,7 +4,7 @@ import re # https://www.python.org/dev/peps/pep-0440 with open(Path(__file__).parent/'damask/VERSION') as f: - version = re.sub(r'(-([^-]*)).*$',r'.\2',re.sub(r'^v(\d+\.\d+(\.\d+)?)',r'\1',f.readline().strip())) + version = re.sub(r'(-([^-]*)).*$',r'.\2',re.sub(r'^v(\d+\.\d+(\.\d+)?)',r'\1',f.readline().strip())) setuptools.setup( name='damask', diff --git a/python/tests/test_seeds.py b/python/tests/test_seeds.py index af27e74af..e68260aa4 100644 --- a/python/tests/test_seeds.py +++ b/python/tests/test_seeds.py @@ -26,6 +26,15 @@ class TestSeeds: cKDTree(coords).query(coords, 2) assert (0<= coords).all() and (coords=distance + @pytest.mark.parametrize('periodic',[True,False]) + def test_from_Poisson_disc_invalid(self,periodic): + N_seeds = np.random.randint(30,300) + N_candidates = N_seeds//15 + distance = np.random.random() + size = np.ones(3)*distance + with pytest.raises(ValueError): + seeds.from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=periodic) + def test_from_grid_reconstruct(self): cells = np.random.randint(10,20,3) N_seeds = np.random.randint(30,300) From 59961a71acc910c8c2cd1fe99c4482637aa0aee4 Mon Sep 17 00:00:00 2001 From: Test User Date: Wed, 28 Apr 2021 19:12:09 +0200 Subject: [PATCH 219/219] [skip ci] updated version information after successful test of v3.0.0-alpha3-40-ga1c46b445 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c2cb2e07b..7942fa57e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha3-37-ge9cfb2f96 +v3.0.0-alpha3-40-ga1c46b445

lBf$S6ns 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 LP81{}jD{aTQ|mgX literal 0 HcmV?d00001 diff --git a/python/tests/reference/Result/read_1.pbz2 b/python/tests/reference/Result/read/test_read[1].pbz2 similarity index 100% rename from python/tests/reference/Result/read_1.pbz2 rename to python/tests/reference/Result/read/test_read[1].pbz2 diff --git a/python/tests/reference/Result/read_2.pbz2 b/python/tests/reference/Result/read/test_read[2].pbz2 similarity index 100% rename from python/tests/reference/Result/read_2.pbz2 rename to python/tests/reference/Result/read/test_read[2].pbz2 diff --git a/python/tests/reference/Result/read_3.pbz2 b/python/tests/reference/Result/read/test_read[3].pbz2 similarity index 100% rename from python/tests/reference/Result/read_3.pbz2 rename to python/tests/reference/Result/read/test_read[3].pbz2 diff --git a/python/tests/reference/Result/read_4.pbz2 b/python/tests/reference/Result/read/test_read[4].pbz2 similarity index 100% rename from python/tests/reference/Result/read_4.pbz2 rename to python/tests/reference/Result/read/test_read[4].pbz2 diff --git a/python/tests/reference/Result/read_5.pbz2 b/python/tests/reference/Result/read/test_read[5].pbz2 similarity index 100% rename from python/tests/reference/Result/read_5.pbz2 rename to python/tests/reference/Result/read/test_read[5].pbz2 diff --git a/python/tests/reference/Result/read_6.pbz2 b/python/tests/reference/Result/read/test_read[6].pbz2 similarity index 100% rename from python/tests/reference/Result/read_6.pbz2 rename to python/tests/reference/Result/read/test_read[6].pbz2 diff --git a/python/tests/reference/Result/read/test_read[7].pbz2 b/python/tests/reference/Result/read/test_read[7].pbz2 new file mode 100644 index 0000000000000000000000000000000000000000..c1e4c31e9cc3876e0bff37bba9f4577bc25e7a25 GIT binary patch literal 7762 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�}YMVC~=sCH_B^}eoWK63;uM6ANYIHrP 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