obsidian_backup/多体+耦合求解器/多体+水动HD+系泊MD.md
2026-02-09 16:23:41 +08:00

9.9 KiB
Raw Blame History

配置文件

  • 配置文件新增MD和MD输入文件路径加在气动后 done
  • 新增p_fast.comp_mooring done

init HD MD初始化

对照FAST_subs.f90 774行附近

IF ( p_FAST%CompHydro == Module_HD ) THEN

对照FAST_subs.f90 919行附近

! initialize CompMooring modules

补充代码 coupled_solver_sub.rs

pub fn fast_init_with_yaml(){}
    if p_fast.comp_hydro == 1 {
	    to be done
    }
    
    if p_fast.comp_mooring == 1{
	    to be done
    }
    
}

模型文件路径data\HEROWIND_models\NREL_5MW_OC4Semi
配置文件Herowind_NREL5MW_ppl_hdmd_calc_config.yaml中气动控制HD MD绝对路径需按需修改

路径使用示例代码: 配置文件参数

calc_config.hydrofile.hydro_input_file
calc_config.mooringfile.mooring_input_file

代码


	// 1 获取运行程序exe所在的路径
    let exe_path: PathBuf = env::current_exe()

        .expect("Unable to get current executable path");

    let exe_dir = exe_path

        .parent()

        .expect("Executable must have a parent directory");
        
     // 2 路径拼接
	 let dll_path = &calc_config.controller_input.dll_path;

	 let dll_full_path = exe_dir.join(dll_path);

	 let dll_full_path_str: &str = dll_full_path.to_str().expect("proxy_path is not valid UTF8");  
      

InitModuleMappings

mapping code

if (p_FAST%CompElast == Module_ED) then
      NumBl   = SIZE(ED%y%BladeRootMotion,1)
      PlatformMotion => ED%y%PlatformPtMesh
      PlatformLoads  => ED%Input(1)%PlatformPtMesh
      
      SubstructureMotion2HD => ED%y%PlatformPtMesh
         SubstructureMotion    => ED%y%PlatformPtMesh
         SubstructureLoads     => ED%Input(1)%PlatformPtMesh

  IF ( SrvD%Input(1)%PtfmMotionMesh%Committed ) THEN
	 CALL MeshMapCreate( PlatformMotion, SrvD%Input(1)%PtfmMotionMesh, MeshMapData%ED_P_2_SrvD_P_P, ErrStat2, ErrMsg2 )
		CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ED_P_2_SrvD_P_P' )
  ENDIF
  
   IF ( p_FAST%CompHydro == Module_HD ) THEN ! HydroDyn-{ElastoDyn or SubDyn}
    
      ! Regardless of the offshore configuration, ED platform motions will be mapped to the PRPMesh of HD
      ! we're just going to assume PlatformLoads and PlatformMotion are committed
      CALL MeshMapCreate( PlatformMotion, HD%Input(1)%PRPMesh, MeshMapData%ED_P_2_HD_PRP_P, ErrStat2, ErrMsg2 )
         CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':ED_P_2_HD_PRP_P' )  
        
        IF ( HD%y%WAMITMesh%Committed  ) THEN ! meshes for floating
            ! HydroDyn WAMIT point mesh to/from ElastoDyn or SD point mesh
         CALL MeshMapCreate( HD%y%WAMITMesh, SubstructureLoads, MeshMapData%HD_W_P_2_SubStructure, ErrStat2, ErrMsg2 )
            CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':HD_W_P_2_SubStructure' )       
         CALL MeshMapCreate( SubstructureMotion2HD, HD%Input(1)%WAMITMesh, MeshMapData%SubStructure_2_HD_W_P, ErrStat2, ErrMsg2 )
            CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':SubStructure_2_HD_W_P' )
      END IF
         
        IF ( HD%Input(1)%Morison%Mesh%Committed  ) THEN  
         CALL MeshMapCreate( HD%y%Morison%Mesh, SubstructureLoads, MeshMapData%HD_M_P_2_SubStructure, ErrStat2, ErrMsg2 )
            CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':HD_M_P_2_SubStructure' )
         CALL MeshMapCreate( SubstructureMotion2HD,  HD%Input(1)%Morison%Mesh, MeshMapData%SubStructure_2_HD_M_P, ErrStat2, ErrMsg2 )
            CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':SubStructure_2_HD_M_P' )                  
      END IF
      
      IF ( p_FAST%CompMooring == Module_MD ) THEN
!-------------------------
!  SubDyn/ElastoDyn <-> MoorDyn
!-------------------------
      ! MoorDyn point mesh to/from SubDyn or ElastoDyn point mesh
         CALL MeshMapCreate( MD%y%CoupledLoads(1), SubstructureLoads,  MeshMapData%Mooring_2_Structure, ErrStat2, ErrMsg2 )
            CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Mooring_2_Structure' )
         CALL MeshMapCreate( SubstructureMotion, MD%Input(1)%CoupledKinematics(1),  MeshMapData%Structure_2_Mooring, ErrStat2, ErrMsg2 )
            CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':Structure_2_Mooring' )
      END IF
      
    IF ( p_FAST%SolveOption == Solve_SimplifiedOpt1 ) THEN
         CALL AllocAry( MeshMapData%Jacobian_Opt1, SizeJac_ED_HD, SizeJac_ED_HD, 'Jacobian for Ptfm-HD coupling', ErrStat2, ErrMsg2 )
         CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName )
         
   IF ( ALLOCATED( MeshMapData%Jacobian_Opt1 ) ) THEN   
      CALL AllocAry( MeshMapData%Jacobian_pivot, SIZE(MeshMapData%Jacobian_Opt1), 'Pivot array for Jacobian LU decomposition', ErrStat2, ErrMsg2 )
         CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName )                 
   END IF
   
         
    CALL ResetRemapFlags(p_FAST, ED, SED, BD, AD, ExtLd, HD, SD, ExtPtfm, SrvD, MAPp, FEAM, MD, Orca, IceF, IceD )      
    
          CALL MeshCopy ( ED%Input(1)%HubPtLoad, MeshMapData%u_ED_HubPtLoad, MESH_NEWCOPY, ErrStat2, ErrMsg2 )      
         CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_ED_HubPtLoad' )                 
            
      CALL MeshCopy ( SubStructureLoads, MeshMapData%SubstructureLoads_Tmp, MESH_NEWCOPY, ErrStat2, ErrMsg2 )
         CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':SubstructureLoads_Tmp' )

      CALL MeshCopy ( SubStructureLoads, MeshMapData%SubstructureLoads_Tmp2, MESH_NEWCOPY, ErrStat2, ErrMsg2 )
         CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':SubstructureLoads_Tmp2' )
         
      CALL MeshCopy ( PlatformLoads, MeshMapData%PlatformLoads_Tmp, MESH_NEWCOPY, ErrStat2, ErrMsg2 )      
         CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':PlatformLoads_Tmp' )                 

      CALL MeshCopy ( PlatformLoads, MeshMapData%PlatformLoads_Tmp2, MESH_NEWCOPY, ErrStat2, ErrMsg2 )      
         CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':PlatformLoads_Tmp2' )  
         

      IF ( p_FAST%CompHydro == Module_HD ) THEN
         
         !TODO: GJH Is this needed, I created it as a place holder, 5/11/2020
         !CALL MeshCopy ( HD%Input(1)%PRPMesh, MeshMapData%u_HD_PRP_Mesh, MESH_NEWCOPY, ErrStat2, ErrMsg2 )      
         !   CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_HD_PRP_Mesh' )
            
         CALL MeshCopy ( HD%Input(1)%WAMITMesh, MeshMapData%u_HD_W_Mesh, MESH_NEWCOPY, ErrStat2, ErrMsg2 )      
            CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_HD_W_Mesh' )                 
                  
         CALL MeshCopy ( HD%Input(1)%Morison%Mesh, MeshMapData%u_HD_M_Mesh, MESH_NEWCOPY, ErrStat2, ErrMsg2 )      
            CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName//':u_HD_M_Mesh' )                         
                                    
      END IF    
      
      END SUBROUTINE InitModuleMappings

SUBROUTINE ResetRemapFlags

   IF ( p_FAST%CompHydro == Module_HD ) THEN
      HD%Input(1)%PRPMesh%RemapFlag       = .FALSE.
      IF (HD%Input(1)%WAMITMesh%Committed) THEN
          HD%Input(1)%WAMITMesh%RemapFlag  = .FALSE.
                 HD%y%WAMITMesh%RemapFlag  = .FALSE.                
      END IF
      IF (HD%Input(1)%Morison%Mesh%Committed) THEN
          HD%Input(1)%Morison%Mesh%RemapFlag  = .FALSE.
                 HD%y%Morison%Mesh%RemapFlag  = .FALSE.
      END IF
   END IF
   
   IF ( p_FAST%CompMooring == Module_MD ) THEN
       MD%Input(1)%CoupledKinematics(1)%RemapFlag     = .FALSE.
              MD%y%CoupledLoads(1)%RemapFlag          = .FALSE.    

solution t0

   if ( P_FAST%CompSeaSt == Module_SeaSt .and. y_FAST%WriteThisStep) then
      ! note: SeaState has no inputs and only calculates WriteOutputs, so we don't need to call CalcOutput unless we are writing to the file
      call SeaSt_CalcOutput( t_initial, SeaSt%u, SeaSt%p, SeaSt%x(1), SeaSt%xd(1), SeaSt%z(1), SeaSt%OtherSt(1), SeaSt%y, SeaSt%m, ErrStat2, ErrMsg2 )
         call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName )
   end if
   
   

CALL CalcOutputs_And_SolveForInputs()

solver_option_2基本没变化

新增 transfer_ServD_to_SD_MD 传递u_MD%DeltaL    =  y_SrvD%CableDeltaL  和  u_MD%DeltaLdot =  y_SrvD%CableDeltaLdot

新增CALL Transfer_Structure_to_Opt1Inputs

Transfer_Structure_to_Opt1Inputs

PlatformMotion => y_ED%PlatformPtMesh
   
   
   IF (p_FAST%CompSub == Module_SD) THEN
      SubstructureMotion => SD%y%y3Mesh
      SubstructureMotion2HD => SD%y%y2Mesh
   ELSE
      SubstructureMotion => PlatformMotion
      SubstructureMotion2HD => PlatformMotion
   ENDIF
   
      IF ( p_FAST%CompHydro == Module_HD ) THEN
   
      CALL Transfer_Point_to_Point( PlatformMotion, u_HD%PRPMesh, MeshMapData%ED_P_2_HD_PRP_P, ErrStat2, ErrMsg2 )
         CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg, RoutineName//' (u_HD%PRPMesh)' )
         
         ! if we don't have a call to SD_CalcOutput, we need to check that p_FAST%CompSub /= Module_SD before this:
      ! IF (p_FAST%CompSub /= Module_SD) THEN
         CALL Transfer_SubStructureMotion_to_HD( SubstructureMotion2HD, u_HD%WAMITMesh, u_HD%Morison%Mesh, MeshMapData, ErrStat2, ErrMsg2 )
            CALL SetErrStat(ErrStat2,ErrMsg2, ErrStat, ErrMsg, RoutineName)
      !END IF ! don't transfer for SubDyn unless we have called SD_CalcOutput
            
   END IF
   
         ELSEIF ( p_FAST%CompMooring == Module_MD ) THEN
            ! motions:
         CALL Transfer_Point_to_Point( SubstructureMotion, u_MD%CoupledKinematics(1), MeshMapData%Structure_2_Mooring, ErrStat2, ErrMsg2 )
            CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat, ErrMsg,RoutineName//'u_MD%CoupledKinematics' )
            

solveoption1

CALL MD_CalcOutput