/* construct extracting dimensions from the name */ MatrixParameterT::MatrixParameterT(const StringT& name_NxM, char variable): ParameterInterfaceT(name_NxM), fVariable(variable), fCopySymmetric(false) { const char caller[] = "MatrixParameterT::MatrixParameterT"; const char msg[] = "could not extract %s dimensions from \"%s\" in \"%s\""; /* resolve suffix */ StringT suffix; suffix.Suffix(name_NxM, '_'); if (suffix.StringLength() < 4) ExceptionT::GeneralFail(caller, msg, "matrix", suffix.Pointer(), name_NxM.Pointer()); /* resolve column dimensions */ StringT num; num.Suffix(suffix, 'x'); if (num.StringLength() < 2 || !isdigit(num[1])) ExceptionT::GeneralFail(caller, msg, "col", num.Pointer(), name_NxM.Pointer()); int col = -1; col = atoi(num.Pointer(1)); if (col < 0) ExceptionT::GeneralFail(caller, msg, "col", num.Pointer(), name_NxM.Pointer()); /* resolve row dimensions */ suffix.Root('x'); if (suffix.StringLength() < 2 || !isdigit(suffix[1])) ExceptionT::GeneralFail(caller, msg, "row", suffix.Pointer(), name_NxM.Pointer()); int row = -1; row = atoi(suffix.Pointer(1)); if (row < 0) ExceptionT::GeneralFail(caller, msg, "row", suffix.Pointer(), name_NxM.Pointer()); /* initialize */ fMatrix.Dimension(row, col); fMatrix = 0.0; }
/* construct extracting length from the name */ VectorParameterT::VectorParameterT(const StringT& name_N, char variable): ParameterInterfaceT(name_N), fVariable(variable) { const char caller[] = "VectorParameterT::VectorParameterT"; const char msg[] = "could not extract length from \"%s\" in \"%s\""; /* resolve length */ StringT suffix; suffix.Suffix(name_N, '_'); if (suffix.StringLength() < 2 || !isdigit(suffix[1])) ExceptionT::GeneralFail(caller, msg, suffix.Pointer(), name_N.Pointer()); int length = -1; length = atoi(suffix.Pointer(1)); if (length < 0) ExceptionT::GeneralFail(caller, msg, suffix.Pointer(), name_N.Pointer()); /* initialize */ fVector.Dimension(length); fVector = 0.0; }
bool TextInputT::Open (const StringT& filename) { /* create file root */ StringT suffix; suffix.Suffix (filename.Pointer()); if (strncmp (suffix.Pointer(), ".geo", 4) == 0 || strncmp (suffix.Pointer(), ".run", 4) == 0 || strncmp (suffix.Pointer(), ".in", 3) == 0) fFileRoot.Root (filename); fFilePath.FilePath(fFileRoot); /* scan geometry file */ ifstreamT geo; if (!OpenFile (geo, ".geo")) { cout << "\n TextInputT::Open: error opening geometry file: " << geo.filename() << endl; return false; } if (!ScanGeometryFile (geo)) { cout << "\n TextInputT::Open: error scanning geometry file: " << geo.filename() << endl; return false; } /* scan results file */ ifstreamT run; if (!OpenFile (run, ".run")) { cout << "\n TextInputT::Open: error opening results file: " << run.filename() << endl; return false; } if (!ScanResultsFile (run)) { cout << "\n TextInputT::Open: error scanning results file: " << run.filename() << endl; return false; } /* must be OK */ return true; }
/* accept parameter list */ void ThermomechanicalCouplingManagerT::TakeParameterList(const ParameterListT& list) { const char caller[] = "ThermomechanicalCouplingManagerT::TakeParameterList"; /* inherited */ // MultiManagerT::TakeParameterList(list); /* inherited - don't call direct base class method */ ParameterInterfaceT::TakeParameterList(list); /* path to parameters file */ StringT path; path.FilePath(fInputFile); TaskT task = kRun; /* parse/validate continuum input */ StringT continuum_input = list.GetParameter("continuum_input"); continuum_input.ToNativePathName(); continuum_input.Prepend(path); ParameterListT continuum_params; ParseInput(continuum_input, continuum_params, true, true, true, fArgv); /* construct continuum solver */ if (fCoarseComm->Size() != 1) ExceptionT::GeneralFail(caller, "parallel execution error"); if (Size() > 1) /* change file name so output files are unique */ { StringT suffix; suffix.Suffix(continuum_input); continuum_input.Root(); continuum_input.Append(".p", Rank()); continuum_input.Append(suffix); } StringT continuum_output_file; continuum_output_file.Root(continuum_input); continuum_output_file.Append(".out"); fCoarseOut.open(continuum_output_file); fCoarse = TB_DYNAMIC_CAST(FEManagerT_bridging*, FEManagerT::New(continuum_params.Name(), continuum_input, fCoarseOut, *fCoarseComm, fArgv, task)); if (!fCoarse) ExceptionT::GeneralFail(caller, "could not construct continuum solver"); fCoarse->TakeParameterList(continuum_params); /* parse/validate atomistic input */ StringT atom_input = list.GetParameter("atom_input"); atom_input.ToNativePathName(); atom_input.Prepend(path); ParameterListT atom_params; ParseInput(atom_input, atom_params, true, true, true, fArgv); /* construct atomistic solver */ if (Size() != fFineComm->Size()) ExceptionT::GeneralFail(caller, "parallel execution error"); StringT atom_output_file; atom_output_file.Root(atom_input); if (Size() > 1) atom_output_file.Append(".p", Rank()); atom_output_file.Append(".out"); fFineOut.open(atom_output_file); fFine = TB_DYNAMIC_CAST(FEManagerT_bridging*, FEManagerT::New(atom_params.Name(), atom_input, fFineOut, *fFineComm, fArgv, task)); if (!fFine) ExceptionT::GeneralFail(caller, "could not construct atomistic solver"); fFine->TakeParameterList(atom_params); /* check consistency between time managers */ TimeManagerT* atom_time = fFine->TimeManager(); TimeManagerT* continuum_time = fCoarse->TimeManager(); /* use parameters from coarse scale solver */ fTimeManager = fCoarse->TimeManager(); fOutputFormat = fCoarse->OutputFormat(); /* don't compute initial conditions */ fFine->SetComputeInitialCondition(false); fCoarse->SetComputeInitialCondition(false); /* resolve bridging fields */ const StringT& bridging_field = list.GetParameter("bridging_field"); fFineField = fFine->NodeManager()->Field(bridging_field); if (!fFineField) ExceptionT::GeneralFail(caller, "could not resolve fine scale \"%s\" field", bridging_field.Pointer()); fCoarseField = fCoarse->NodeManager()->Field(bridging_field); if (!fFineField) ExceptionT::GeneralFail(caller, "could not resolve coarse scale \"%s\" field", bridging_field.Pointer()); /* resolve integrator types */ // if (fFineField->Integrator().ImplicitExplicit() != fCoarseField->Integrator().ImplicitExplicit()) // ExceptionT::GeneralFail(caller, "time integrator mismatch"); fImpExp = fFineField->Integrator().ImplicitExplicit(); /* collect the ghost atom ID list */ ArrayT<StringT> ghost_atom_ID; const ParameterListT* ghosts = list.List("ghost_atom_ID_list"); if (ghosts) StringListT::Extract(*ghosts, ghost_atom_ID); /* configure projection/interpolation */ NodeManagerT& fine_node_manager = *(fFine->NodeManager()); int group = 0; int order1 = 0; bool make_inactive = true; bool node_to_node = false; fFine->InitGhostNodes(fFineField->FieldName(), ghost_atom_ID, fCoarse->ProjectImagePoints()); fCoarse->InitInterpolation(fFineField->FieldName(), fFine->GhostNodes(), fine_node_manager.InitialCoordinates()); fCoarse->InitProjection(fFineField->FieldName(), *(fFine->CommManager()), fFine->NonGhostNodes(), fine_node_manager, make_inactive, node_to_node); /* send coarse/fine output through the fFine output */ int ndof = fFine->NodeManager()->NumDOF(group); ArrayT<StringT> labels(2*ndof); const char* coarse_labels[] = {"UC_X", "UC_Y", "UC_Z"}; const char* fine_labels[] = {"UF_X", "UF_Y", "UF_Z"}; int dex = 0; for (int i = 0; i < ndof; i++) labels[dex++] = coarse_labels[i]; for (int i = 0; i < ndof; i++) labels[dex++] = fine_labels[i]; const iArrayT& non_ghost_nodes = fFine->NonGhostNodes(); fAtomConnectivities.Alias(non_ghost_nodes.Length(), 1, non_ghost_nodes.Pointer()); OutputSetT output_set(GeometryT::kPoint, fAtomConnectivities, labels, false); fOutputID = fFine->RegisterOutput(output_set); /* construct solver */ int n1 = fFine->NumGroups(); int n2 = fCoarse->NumGroups(); // if (n1 != n2) ExceptionT::GeneralFail(caller, "number of groups must match: %d != %d", n1, n2); const ParameterListT* multi_solver = list.ListChoice(*this, "multi_solver_choice"); if (multi_solver) { /* construct */ SolverT* solver = SolverT::New(*this, multi_solver->Name(), 0); if (!solver) ExceptionT::GeneralFail(caller, "could not construct solver \"%s\"", multi_solver->Name().Pointer()); solver->TakeParameterList(*multi_solver); /* store */ fSolvers.Dimension(1); fSolvers[0] = solver; } SetSolver(); /* default solver phases */ fMaxSolverLoops = 1; fSolverPhases.Dimension(1, 3); fSolverPhases(0,0) = 0; fSolverPhases(0,1) =-1; fSolverPhases(0,2) =-1; fSolverPhasesStatus.Dimension(fSolverPhases.MajorDim(), kNumStatusFlags); fSolverPhasesStatus = 0; /* terms to include in the equilibrium equations */ fFineToCoarse = list.GetParameter("fine_to_coarse"); fCoarseToFine = list.GetParameter("coarse_to_fine"); if (fCoarseToFine) /* enforce zero bond density in projected cells */ fCoarse->DeactivateFollowerCells(); /* needed to solve overlap */ const dArray2DT& fine_init_coords = fine_node_manager.InitialCoordinates(); const ParticlePairT* particle_pair = fFine->ParticlePair(); if (!particle_pair) ExceptionT::GeneralFail(caller, "could not resolve ParticlePairT"); /* overlap correction method */ StringT overlap_path; const ParameterT* overlap_file = list.Parameter("overlap_file"); if (overlap_file) { overlap_path = *overlap_file; overlap_path.ToNativePathName(); StringT path; path.FilePath(fInputFile); overlap_path.Prepend(path); } /* default name */ else { overlap_path.Root(fInputFile); overlap_path.Append(".overlap"); } const ParameterListT& overlap = list.GetListChoice(*this, "overlap_correction_choice"); if (overlap.Name() == "prescribe_overlap") { double density = overlap.GetParameter("bond_density"); cout << "\n " << caller << ": \"prescribe_overlap\" not implemented. p = 1.0" << endl; } else if (overlap.Name() == "by-bond_multiplier") { /* extract parameters */ double smoothing = overlap.GetParameter("smoothing"); double bind_1 = overlap.GetParameter("bind_to_1.0"); double reg = overlap.GetParameter("constraint_regularization"); int nip = overlap.GetParameter("density_nip"); double init_bound_width = overlap.GetParameter("init_bound_width"); /* compute overlap correction */ double bound_0 = init_bound_width/2.0; fCoarse->CorrectOverlap_2(particle_pair->Neighbors(), fine_init_coords, overlap_path, smoothing, bind_1, reg, bound_0, nip); } else if (overlap.Name() == "by-bond_penalty") { /* extract parameters */ double smoothing = overlap.GetParameter("smoothing"); double bind_1 = overlap.GetParameter("bind_to_1.0"); double bound_tol = overlap.GetParameter("bound_tolerance"); double stiffness_jump = overlap.GetParameter("stiffness_jump"); int nip = overlap.GetParameter("density_nip"); /* compute overlap correction */ fCoarse->CorrectOverlap_22(particle_pair->Neighbors(), fine_init_coords, overlap_path, smoothing, bind_1, bound_tol, stiffness_jump, nip); } else ExceptionT::GeneralFail(caller, "unrecognized overlap correction method \"%s\"", overlap.Name().Pointer()); /* output for kinetic temperature */ ModelManagerT* model = fCoarse->ModelManager(); ArrayT<StringT> vlabels(1); const char* label[] = {"kT"}; vlabels[0] = label[0]; /* specify output - "free set" */ const char* id = "1"; StringT ID ; // HACK ID = fCoarse->ElementGroup(0)->ElementBlockID(1); OutputSetT coarse_output_set(model->ElementGroupGeometry(ID), model->ElementGroup(ID), vlabels); fCoarseOutputID = fCoarse->RegisterOutput(coarse_output_set); /* find particle class */ for (int i = 0; i < fFine->NumElementGroups(); i++) { ElementBaseT* element_base = fFine->ElementGroup(i); ParticleT* particle = dynamic_cast<ParticleT*>(element_base); if (particle) { fParticles = particle; } } }