//-------------------------------------------------------- // constuct a Green's submatrix //-------------------------------------------------------- void ChargeRegulatorMethodFeedback::set_influence_matrix(void) { // construct control-influence matrix bar{G}^-1: ds{p} = G{p,m}^-1 dphi{m} // if (nInfluenceNodes_ < nControlNodes_) throw ATC_Error(" least square not implmented "); if (nInfluenceNodes_ > nControlNodes_) throw ATC_Error(" solve not possible "); DENS_MAT G(nInfluenceNodes_,nControlNodes_); DENS_VEC G_I; set<int>::const_iterator itr,itr2,itr3; const Array<int> & nmap = atc_->fe_engine()->fe_mesh()->global_to_unique_map(); int i = 0; for (itr = influenceNodes_.begin(); itr != influenceNodes_.end(); itr++) { poissonSolver_->greens_function(*itr, G_I); int j = 0; for (itr2 = controlNodes_.begin(); itr2 != controlNodes_.end(); itr2++) { int jnode = nmap(*itr2); G(i,j++) = G_I(jnode); } i++; } invG_ = inv(G); // construct the prolong-restrict projector N N^T for influence nodes only InterscaleManager & interscaleManager(atc_->interscale_manager()); const SPAR_MAT & N_Ia = (boundary_) ? (interscaleManager.per_atom_sparse_matrix("InterpolantGhost"))->quantity(): (interscaleManager.per_atom_sparse_matrix("Interpolant"))->quantity(); NT_.reset(nInfluenceAtoms_,nInfluenceNodes_); DENS_MAT NNT(nInfluenceNodes_,nInfluenceNodes_); int k = 0; for (itr3 = influenceAtoms_.begin(); itr3 != influenceAtoms_.end(); itr3++) { int katom = *itr3; int i = 0; for (itr = influenceNodes_.begin(); itr != influenceNodes_.end(); itr++) { int Inode = *itr; int j = 0; NT_(k,i) = N_Ia(katom,Inode); for (itr2 = influenceNodes_.begin(); itr2 != influenceNodes_.end(); itr2++) { int Jnode = *itr2; NNT(i,j++) += N_Ia(katom,Inode)*N_Ia(katom,Jnode); } i++; } k++; } // swap contributions across processors DENS_MAT localNNT = NNT; int count = NNT.nRows()*NNT.nCols(); lammpsInterface_->allsum(localNNT.ptr(),NNT.ptr(),count); invNNT_ = inv(NNT); // total influence matrix if (nInfluenceAtoms_ > 0) { NTinvNNTinvG_ = NT_*invNNT_*invG_; } }
//-------------------------------------------------------------------------- void HexNElementDescription::set_base_node_maps() { nodeMap.resize(nodesPerElement); inverseNodeMap.resize(nodesPerElement); nmap(0 , 0 , 0 ) = 0; nmap(polyOrder, 0 , 0 ) = 1; nmap(polyOrder, polyOrder, 0 ) = 2; nmap(0 , polyOrder, 0 ) = 3; nmap(0 , 0 , polyOrder) = 4; nmap(polyOrder, 0 , polyOrder) = 5; nmap(polyOrder, polyOrder, polyOrder) = 6; nmap(0 , polyOrder, polyOrder) = 7; }
//-------------------------------------------------------------------------- void HexNElementDescription::set_tensor_product_node_mappings() { set_base_node_maps(); if (polyOrder > 1) { for (int edgeOrdinal = 0; edgeOrdinal < numEdges; ++edgeOrdinal) { auto newNodeOrdinals = edgeNodeConnectivities.at(edgeOrdinal); for (int k = 0; k < newNodesPerEdge; ++k) { for (int j = 0; j < newNodesPerEdge; ++j) { for (int i = 0; i < newNodesPerEdge; ++i) { auto offsets = get_edge_offsets(i,j,k,edgeOrdinal); nodeMap.at(offsets.first) = newNodeOrdinals.at(offsets.second); } } } } for (int faceOrdinal = 0; faceOrdinal < numFaces; ++faceOrdinal) { auto newNodeOrdinals = faceNodeConnectivities.at(faceOrdinal); for (int k = 0; k < newNodesPerEdge; ++k) { for (int j = 0; j < newNodesPerEdge; ++j) { for (int i = 0; i < newNodesPerEdge; ++i) { auto offsets = get_face_offsets(i,j,k,faceOrdinal); nodeMap.at(offsets.first) = newNodeOrdinals.at(offsets.second); } } } } auto newVolumeNodes = volumeNodeConnectivities.at(0); for (int k = 0; k < newNodesPerEdge; ++k) { for (int j = 0; j < newNodesPerEdge; ++j) { for (int i = 0; i < newNodesPerEdge; ++i) { nmap(i + 1, j + 1, k + 1) = newVolumeNodes.at(i + newNodesPerEdge * (j + newNodesPerEdge * k)); } } } } //inverse map inverseNodeMap.resize(nodes1D*nodes1D*nodes1D); for (int i = 0; i < nodes1D; ++i) { for (int j = 0; j < nodes1D; ++j) { for (int k = 0; k < nodes1D; ++k) { inverseNodeMap[node_map(i,j,k)] = {i, j, k}; } } } }